From ce6a9ff965c6b99ee966eee159baa8c35e135635 Mon Sep 17 00:00:00 2001 From: Yan Xu Date: Tue, 17 Mar 2026 15:51:08 +0800 Subject: [PATCH 01/11] upgrade nodejs from 20 to 24 and update dependencies (#578) * upgrade nodejs from 20 to 24 and update dependencies * update installation step of ps * update az account count check * upgrade actions/checkout and actions/setup-node from 4 to 6 * remove empty lines --- .github/CODEOWNERS | 2 +- .github/workflows/azure-login-canary.yml | 3 +- .github/workflows/azure-login-negative.yml | 16 +- .github/workflows/azure-login-positive.yml | 37 +-- .github/workflows/azure-login-pr-check.yml | 10 +- .github/workflows/ci.yml | 8 +- .github/workflows/codeql.yml | 2 +- .github/workflows/markdownlint.yml | 6 +- action.yml | 2 +- package-lock.json | 254 +++++++-------------- package.json | 4 +- 11 files changed, 127 insertions(+), 217 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 27a83c107..d3a965c25 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -@kaverma @kanika1894 @BALAGA-GAYATRI @pulkitaggarwl +@YanaXu diff --git a/.github/workflows/azure-login-canary.yml b/.github/workflows/azure-login-canary.yml index 5c430f703..eb4ef84de 100644 --- a/.github/workflows/azure-login-canary.yml +++ b/.github/workflows/azure-login-canary.yml @@ -30,7 +30,7 @@ jobs: az --version - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: 'Az CLI login with subscription' uses: azure/login@v1 @@ -89,4 +89,3 @@ jobs: - name: Post to slack shell: bash run: curl -X POST -H 'Content-type:application/json' --data '{"blocks":[{"type":"section","text":{"type":"mrkdwn","text":"${{steps.slack_report.outputs.report}}"}}]}' https://hooks.slack.com/services/${{SECRETS.SLACK_CHANNEL_SECRET}} - diff --git a/.github/workflows/azure-login-negative.yml b/.github/workflows/azure-login-negative.yml index 91dda5801..7998fa08c 100644 --- a/.github/workflows/azure-login-negative.yml +++ b/.github/workflows/azure-login-negative.yml @@ -19,12 +19,12 @@ jobs: steps: - name: 'Checking out repo code' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - name: Set Node.js 20.x for GitHub Action - uses: actions/setup-node@v4 + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 with: - node-version: 20.x + node-version: 24.x - name: 'Validate build' run: | @@ -82,12 +82,12 @@ jobs: steps: - name: 'Checking out repo code' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - name: Set Node.js 20.x for GitHub Action - uses: actions/setup-node@v4 + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 with: - node-version: 20.x + node-version: 24.x - name: 'Validate build' run: | diff --git a/.github/workflows/azure-login-positive.yml b/.github/workflows/azure-login-positive.yml index 16d15019c..ecb102f84 100644 --- a/.github/workflows/azure-login-positive.yml +++ b/.github/workflows/azure-login-positive.yml @@ -18,12 +18,12 @@ jobs: steps: - name: 'Checking out repo code' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - name: Set Node.js 20.x for GitHub Action - uses: actions/setup-node@v4 + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 with: - node-version: 20.x + node-version: 24.x - name: 'Validate build' run: | @@ -110,12 +110,12 @@ jobs: steps: - name: 'Checking out repo code' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - name: Set Node.js 20.x for GitHub Action - uses: actions/setup-node@v4 + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 with: - node-version: 20.x + node-version: 24.x - name: 'Validate build' run: | @@ -203,7 +203,7 @@ jobs: - name: Run Azure Cli shell: pwsh run: | - $checkResult = (az account list --output json | ConvertFrom-Json).Count -eq 3 + $checkResult = (az account list --output json | ConvertFrom-Json).Count -eq 2 if(-not $checkResult){ throw "Not all checks passed!" } @@ -245,12 +245,12 @@ jobs: environment: Automation test steps: - name: 'Checking out repo code' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - name: Set Node.js 20.x for GitHub Action - uses: actions/setup-node@v4 + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 with: - node-version: 20.x + node-version: 24.x - name: Install Azure CLI run: | @@ -265,11 +265,12 @@ jobs: - name: Install Powershell run: | apt-get update - apt-get install -y wget - wget https://ftp.debian.org/debian/pool/main/i/icu/libicu72_72.1-3_amd64.deb - dpkg -i libicu72_72.1-3_amd64.deb - wget https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/powershell_7.5.0-1.deb_amd64.deb - dpkg -i powershell_7.5.0-1.deb_amd64.deb + apt-get install -y wget apt-transport-https software-properties-common + wget -q "https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb" + dpkg -i packages-microsoft-prod.deb + rm packages-microsoft-prod.deb + apt-get update + apt-get install -y powershell - name: Check Powershell Version shell: pwsh diff --git a/.github/workflows/azure-login-pr-check.yml b/.github/workflows/azure-login-pr-check.yml index 279cf3cd7..b0cf457b9 100644 --- a/.github/workflows/azure-login-pr-check.yml +++ b/.github/workflows/azure-login-pr-check.yml @@ -10,16 +10,16 @@ jobs: runs-on: windows-latest steps: - name: Checkout from PR branch - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.event.pull_request.head.ref }} - # Using 20.x version as an example - - name: Set Node.js 20.x for GitHub Action - uses: actions/setup-node@v4 + # Using 24.x version as an example + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 with: - node-version: 20.x + node-version: 24.x - name: installing node_modules run: npm install diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 45da7c8a3..f128428c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,12 +18,12 @@ jobs: steps: - name: 'Checking out repo code' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - name: Set Node.js 20.x for GitHub Action - uses: actions/setup-node@v4 + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 with: - node-version: 20.x + node-version: 24.x - name: 'Validate build' run: | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ca4c475ec..0ccb3a2ff 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 76c8789ec..5c13f1674 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -7,11 +7,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Use Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 20.x + node-version: 24.x - name: Run Markdownlint run: | npm i -g markdownlint-cli2 diff --git a/action.yml b/action.yml index 44c1f66a6..bf52a453b 100644 --- a/action.yml +++ b/action.yml @@ -38,7 +38,7 @@ branding: icon: 'login.svg' color: 'blue' runs: - using: 'node20' + using: 'node24' main: 'lib/main/index.js' post-if: (!env.AZURE_LOGIN_POST_CLEANUP || env.AZURE_LOGIN_POST_CLEANUP != 'false') post: 'lib/cleanup/index.js' diff --git a/package-lock.json b/package-lock.json index d0ef42c4a..a0c620929 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "login", - "version": "2.2.0", + "version": "3.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "login", - "version": "2.2.0", + "version": "3.0.0", "license": "MIT", "dependencies": { "@actions/core": "1.9.1", @@ -16,7 +16,7 @@ }, "devDependencies": { "@types/jest": "^29.2.4", - "@types/node": "^20.11.1", + "@types/node": "^24.0.0", "@vercel/ncc": "^0.38.1", "jest": "^29.3.1", "jest-circus": "^29.3.1", @@ -77,73 +77,20 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/compat-data": { "version": "7.20.5", "dev": true, @@ -321,7 +268,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { @@ -329,7 +278,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -345,91 +296,28 @@ } }, "node_modules/@babel/helpers": { - "version": "7.20.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.23.4", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/types": "^7.29.0" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.9", - "dev": true, - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -601,13 +489,15 @@ } }, "node_modules/@babel/template": { - "version": "7.23.9", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -634,13 +524,14 @@ } }, "node_modules/@babel/types": { - "version": "7.23.9", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -1077,11 +968,13 @@ } }, "node_modules/@types/node": { - "version": "20.11.19", + "version": "24.12.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz", + "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~7.16.0" } }, "node_modules/@types/prettier": { @@ -1270,7 +1163,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -1468,7 +1363,9 @@ "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -1668,6 +1565,21 @@ "version": "1.0.0", "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.1", "dev": true, @@ -1750,14 +1662,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/html-escaper": { "version": "2.0.2", "dev": true, @@ -2482,11 +2386,15 @@ }, "node_modules/js-tokens": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.14.1", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -2557,7 +2465,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "license": "MIT" }, "node_modules/lodash.memoize": { @@ -2609,11 +2519,13 @@ "license": "MIT" }, "node_modules/micromatch": { - "version": "4.0.5", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -2629,7 +2541,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -2805,7 +2719,9 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.0", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, @@ -3121,14 +3037,6 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3237,7 +3145,9 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index 1ebd3012a..c1bb09287 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "login", - "version": "2.2.0", + "version": "3.0.0", "description": "Login Azure wraps the az login, allowing for Azure actions to log into Azure", "main": "lib/main/index.js", "scripts": { @@ -13,7 +13,7 @@ "license": "MIT", "devDependencies": { "@types/jest": "^29.2.4", - "@types/node": "^20.11.1", + "@types/node": "^24.0.0", "@vercel/ncc": "^0.38.1", "jest": "^29.3.1", "jest-circus": "^29.3.1", From 893aa84218880a3fafd9a6d332ff1aea7108f1fe Mon Sep 17 00:00:00 2001 From: Yan Xu Date: Tue, 17 Mar 2026 16:26:43 +0800 Subject: [PATCH 02/11] upgrade Azure Login Action version in README (#579) --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 615c032f3..0241d309f 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Azure login - uses: azure/login@v2 + uses: azure/login@v3 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} @@ -223,7 +223,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Azure login - uses: azure/login@v2 + uses: azure/login@v3 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} @@ -285,7 +285,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: azure/login@v2 + - uses: azure/login@v3 with: creds: ${{ secrets.AZURE_CREDENTIALS }} @@ -312,7 +312,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: azure/login@v2 + - uses: azure/login@v3 with: creds: ${{ secrets.AZURE_CREDENTIALS }} enable-AzPSSession: true @@ -335,7 +335,7 @@ jobs: If you want to pass subscription ID, tenant ID, client ID, and client secret as individual parameters instead of bundling them in a single JSON object to address the [security concerns](https://docs.github.com/actions/security-guides/encrypted-secrets), below snippet can help with the same. ```yaml - - uses: azure/login@v2 + - uses: azure/login@v3 with: creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZURE_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}' ``` @@ -379,7 +379,7 @@ jobs: runs-on: self-hosted steps: - name: Azure login - uses: azure/login@v2 + uses: azure/login@v3 with: auth-type: IDENTITY tenant-id: ${{ secrets.AZURE_TENANT_ID }} @@ -445,7 +445,7 @@ jobs: runs-on: self-hosted steps: - name: Azure login - uses: azure/login@v2 + uses: azure/login@v3 with: auth-type: IDENTITY client-id: ${{ secrets.AZURE_CLIENT_ID }} @@ -485,7 +485,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: azure/login@v2 + - uses: azure/login@v3 with: creds: ${{ secrets.AZURE_CREDENTIALS }} environment: 'AzureUSGovernment' @@ -507,7 +507,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: azure/login@v2 + - uses: azure/login@v3 with: creds: ${{ secrets.AZURE_CREDENTIALS }} environment: 'AzureStack' @@ -534,7 +534,7 @@ jobs: steps: - name: Azure Login - uses: azure/login@v2 + uses: azure/login@v3 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} @@ -597,7 +597,7 @@ jobs: # enable cleanup for the 1st Azure Login - name: Azure Login - uses: azure/login@v2 + uses: azure/login@v3 env: AZURE_LOGIN_PRE_CLEANUP: true AZURE_LOGIN_POST_CLEANUP: true @@ -611,7 +611,7 @@ jobs: # disable cleanup for all other Azure Login - name: Azure Login 2 - uses: azure/login@v2 + uses: azure/login@v3 env: AZURE_LOGIN_PRE_CLEANUP: false AZURE_LOGIN_POST_CLEANUP: false @@ -625,7 +625,7 @@ jobs: # disable cleanup for all other Azure Login - name: Azure Login 3 - uses: azure/login@v2 + uses: azure/login@v3 env: AZURE_LOGIN_PRE_CLEANUP: false AZURE_LOGIN_POST_CLEANUP: false @@ -652,7 +652,7 @@ jobs: steps: - name: Azure Login - uses: azure/login@v2 + uses: azure/login@v3 env: AZURE_LOGIN_PRE_CLEANUP: ${{ startsWith(runner.name, 'GitHub Actions') }} AZURE_LOGIN_POST_CLEANUP: ${{ startsWith(runner.name, 'GitHub Actions') }} From 9dfca5820a9055ed36abbd5b5710ace9f209ead5 Mon Sep 17 00:00:00 2001 From: Yan Xu Date: Tue, 24 Mar 2026 10:12:40 +0800 Subject: [PATCH 03/11] use the latest auzre/powershell@v3 (#581) --- .../azure-login-integration-tests.yml | 10 +++++----- .github/workflows/azure-login-negative.yml | 8 ++++---- .github/workflows/azure-login-positive.yml | 18 +++++++++--------- README.md | 12 ++++++------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/azure-login-integration-tests.yml b/.github/workflows/azure-login-integration-tests.yml index 120b5a71b..a746e74f0 100644 --- a/.github/workflows/azure-login-integration-tests.yml +++ b/.github/workflows/azure-login-integration-tests.yml @@ -37,7 +37,7 @@ jobs: creds: ${{ secrets.AZURE_CREDENTIALS }} enable-AzPSSession: true - - uses: azure/powershell@v1 + - uses: azure/powershell@v3 with: inlineScript: "(Get-AzContext).Environment.Name" azPSVersion: "latest" @@ -49,7 +49,7 @@ jobs: enable-AzPSSession: true allow-no-subscriptions: true - - uses: azure/powershell@v1 + - uses: azure/powershell@v3 with: inlineScript: "(Get-AzContext).Environment.Name" azPSVersion: "latest" @@ -87,7 +87,7 @@ jobs: subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID }} enable-AzPSSession: true - - uses: azure/powershell@v1 + - uses: azure/powershell@v3 with: inlineScript: "(Get-AzContext).Environment.Name" azPSVersion: "latest" @@ -100,7 +100,7 @@ jobs: enable-AzPSSession: true allow-no-subscriptions: true - - uses: azure/powershell@v1 + - uses: azure/powershell@v3 with: inlineScript: "(Get-AzContext).Environment.Name" azPSVersion: "latest" @@ -126,4 +126,4 @@ jobs: - name: Post to slack shell: bash - run: curl -X POST -H 'Content-type:application/json' --data '{"blocks":[{"type":"section","text":{"type":"mrkdwn","text":"${{steps.slack_report.outputs.report}}"}}]}' https://hooks.slack.com/services/${{SECRETS.SLACK_CHANNEL_SECRET}} + run: curl -X POST -H 'Content-type:application/json' --data '{"blocks":[{"type":"section","text":{"type":"mrkdwn","text":"${{steps.slack_report.outputs.report}}"}}]}' https://hooks.slack.com/services/${{SECRETS.SLACK_CHANNEL_SECRET}} diff --git a/.github/workflows/azure-login-negative.yml b/.github/workflows/azure-login-negative.yml index 7998fa08c..37c39faed 100644 --- a/.github/workflows/azure-login-negative.yml +++ b/.github/workflows/azure-login-negative.yml @@ -58,7 +58,7 @@ jobs: - name: Run Azure PowerShell id: ps_3 continue-on-error: true - uses: azure/powershell@v1 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -186,7 +186,7 @@ jobs: - name: Run Azure PowerShell id: ps_8 continue-on-error: true - uses: azure/powershell@v1 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -216,7 +216,7 @@ jobs: - name: Run Azure PowerShell id: ps_9 continue-on-error: true - uses: azure/powershell@v1 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -332,4 +332,4 @@ jobs: uses: actions/github-script@v7 with: script: | - core.setFailed('Last action should fail but not. Please check it.') + core.setFailed('Last action should fail but not. Please check it.') diff --git a/.github/workflows/azure-login-positive.yml b/.github/workflows/azure-login-positive.yml index ecb102f84..340d3b828 100644 --- a/.github/workflows/azure-login-positive.yml +++ b/.github/workflows/azure-login-positive.yml @@ -47,7 +47,7 @@ jobs: az vm list --output none - name: Run Azure PowerShell - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -69,7 +69,7 @@ jobs: az account show --output none - name: Run Azure PowerShell again - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -92,7 +92,7 @@ jobs: az vm list --output none - name: Run Azure PowerShell - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -160,7 +160,7 @@ jobs: az vm list --output none - name: Run Azure PowerShell - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -183,7 +183,7 @@ jobs: az account show --output none - name: Run Azure PowerShell again - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -209,7 +209,7 @@ jobs: } - name: Run Azure PowerShell - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -230,7 +230,7 @@ jobs: az account show --output none - name: Run Azure PowerShell - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -309,8 +309,8 @@ jobs: az group list --output none - name: Run Azure PowerShell again - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | - $checkResult = Get-AzResourceGroup + $checkResult = Get-AzResourceGroup diff --git a/README.md b/README.md index 0241d309f..a031ca763 100644 --- a/README.md +++ b/README.md @@ -238,7 +238,7 @@ jobs: az account show - name: Azure PowerShell script - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -325,7 +325,7 @@ jobs: az account show - name: Azure PowerShell script - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -396,7 +396,7 @@ jobs: az account show - name: Azure PowerShell script - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -463,7 +463,7 @@ jobs: az account show - name: Azure PowerShell script - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -549,7 +549,7 @@ jobs: az account show - name: Run Azure PowerShell - uses: azure/powershell@v2 + uses: azure/powershell@v3 with: azPSVersion: "latest" inlineScript: | @@ -705,4 +705,4 @@ provided by the bot. You will only need to do this once across all repos using o This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. From a8420072e8906b1dc28363b8731497e0fb1f81d9 Mon Sep 17 00:00:00 2001 From: Yeming Liu <11371776+isra-fel@users.noreply.github.com> Date: Thu, 30 Jul 2026 10:40:28 +1000 Subject: [PATCH 04/11] Update CODEOWNERS (#598) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d3a965c25..f9bb67a67 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -@YanaXu +@Azure/act-identity-squad From e82415a0b9080e85d20936cbd8e3dfdb4e581d73 Mon Sep 17 00:00:00 2001 From: MaddyMicrosoft Date: Thu, 30 Jul 2026 11:02:53 +1000 Subject: [PATCH 05/11] Add IDE files to .gitignore (#597) --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 18e337ddd..fef07358f 100644 --- a/.gitignore +++ b/.gitignore @@ -94,6 +94,12 @@ typings/ .DS_Store Thumbs.db +# IDE / editor +.vs/ +.vscode/ +.idea/ +*.swp + # Ignore built ts files __tests__/runner/* lib/**/* \ No newline at end of file From f4dcb8098222abd564648c10ad073a119a6e2dba Mon Sep 17 00:00:00 2001 From: MaddyMicrosoft Date: Tue, 4 Aug 2026 11:21:18 +1000 Subject: [PATCH 06/11] Escape single quotes in PowerShell login script inputs (#599) Apply the same single-quote escape already used for the service principal secret to the remaining values interpolated into the generated PowerShell login script: tenant-id, subscription-id, client-id, federated token, and the AzureStack resourceManagerEndpointUrl. Factor the escape into a shared helper (escapePSSingleQuoted) so every interpolation site uses the same treatment, and add regression tests that assert each field is escaped across all supported auth paths. No behaviour change for valid inputs; legitimate values contain no single quotes. --- .../PowerShell/AzPSScriptBuilder.test.ts | 153 ++++++++++++++++++ src/PowerShell/AzPSScriptBuilder.ts | 28 +++- 2 files changed, 173 insertions(+), 8 deletions(-) diff --git a/__tests__/PowerShell/AzPSScriptBuilder.test.ts b/__tests__/PowerShell/AzPSScriptBuilder.test.ts index 862d7a0f5..76b32c244 100644 --- a/__tests__/PowerShell/AzPSScriptBuilder.test.ts +++ b/__tests__/PowerShell/AzPSScriptBuilder.test.ts @@ -150,4 +150,157 @@ describe("Getting AzLogin PS script", () => { }); }); + const INJECT_RAW = "abc' ; Start-Process calc ; $x='"; + const INJECT_ESCAPED = "abc'' ; Start-Process calc ; $x=''"; + + test('SECURITY: tenant-id single quote is escaped (SP+secret path)', () => { + setEnv('environment', 'azurecloud'); + setEnv('enable-AzPSSession', 'true'); + setEnv('allow-no-subscriptions', 'true'); + setEnv('auth-type', 'SERVICE_PRINCIPAL'); + let creds = { + 'clientId': 'client-id', + 'clientSecret': 'client-secret', + 'tenantId': INJECT_RAW, + 'subscriptionId': 'subscription-id' + } + setEnv('creds', JSON.stringify(creds)); + + let loginConfig = new LoginConfig(); + loginConfig.initialize(); + return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([_, loginScript]) => { + expect(loginScript).toContain(`-Tenant '${INJECT_ESCAPED}'`); + expect(loginScript).not.toContain(`-Tenant '${INJECT_RAW}'`); + }); + }); + + test('SECURITY: subscription-id single quote is escaped (SP+secret path)', () => { + setEnv('environment', 'azurecloud'); + setEnv('enable-AzPSSession', 'true'); + setEnv('allow-no-subscriptions', 'true'); + setEnv('auth-type', 'SERVICE_PRINCIPAL'); + let creds = { + 'clientId': 'client-id', + 'clientSecret': 'client-secret', + 'tenantId': 'tenant-id', + 'subscriptionId': INJECT_RAW + } + setEnv('creds', JSON.stringify(creds)); + + let loginConfig = new LoginConfig(); + loginConfig.initialize(); + return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([_, loginScript]) => { + expect(loginScript).toContain(`-Subscription '${INJECT_ESCAPED}'`); + expect(loginScript).not.toContain(`-Subscription '${INJECT_RAW}'`); + }); + }); + + test('SECURITY: client-id single quote is escaped (SP+secret path, PSCredential)', () => { + setEnv('environment', 'azurecloud'); + setEnv('enable-AzPSSession', 'true'); + setEnv('allow-no-subscriptions', 'true'); + setEnv('auth-type', 'SERVICE_PRINCIPAL'); + let creds = { + 'clientId': INJECT_RAW, + 'clientSecret': 'client-secret', + 'tenantId': 'tenant-id', + 'subscriptionId': 'subscription-id' + } + setEnv('creds', JSON.stringify(creds)); + + let loginConfig = new LoginConfig(); + loginConfig.initialize(); + return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([_, loginScript]) => { + expect(loginScript).toContain(`New-Object System.Management.Automation.PSCredential('${INJECT_ESCAPED}',`); + expect(loginScript).not.toContain(`New-Object System.Management.Automation.PSCredential('${INJECT_RAW}',`); + }); + }); + + test('SECURITY: client-id single quote is escaped (OIDC path)', () => { + setEnv('environment', 'azurecloud'); + setEnv('enable-AzPSSession', 'true'); + setEnv('allow-no-subscriptions', 'false'); + setEnv('tenant-id', 'tenant-id'); + setEnv('subscription-id', 'subscription-id'); + setEnv('client-id', INJECT_RAW); + setEnv('auth-type', 'SERVICE_PRINCIPAL'); + + let loginConfig = new LoginConfig(); + loginConfig.initialize(); + jest.spyOn(loginConfig, 'getFederatedToken').mockImplementation(async () => { loginConfig.federatedToken = "fake-token"; }); + return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([_, loginScript]) => { + expect(loginScript).toContain(`-ApplicationId '${INJECT_ESCAPED}'`); + expect(loginScript).not.toContain(`-ApplicationId '${INJECT_RAW}'`); + }); + }); + + test('SECURITY: client-id single quote is escaped (user-assigned MI path)', () => { + setEnv('environment', 'azurecloud'); + setEnv('enable-AzPSSession', 'true'); + setEnv('allow-no-subscriptions', 'true'); + setEnv('auth-type', 'IDENTITY'); + setEnv('client-id', INJECT_RAW); + + let loginConfig = new LoginConfig(); + loginConfig.initialize(); + return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([_, loginScript]) => { + expect(loginScript).toContain(`-AccountId '${INJECT_ESCAPED}'`); + expect(loginScript).not.toContain(`-AccountId '${INJECT_RAW}'`); + }); + }); + + test('SECURITY: tenant-id and subscription-id single quotes are escaped (system-assigned MI path)', () => { + setEnv('environment', 'azurecloud'); + setEnv('enable-AzPSSession', 'true'); + setEnv('allow-no-subscriptions', 'false'); + setEnv('tenant-id', INJECT_RAW); + setEnv('subscription-id', INJECT_RAW); + setEnv('auth-type', 'IDENTITY'); + + let loginConfig = new LoginConfig(); + loginConfig.initialize(); + return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([_, loginScript]) => { + expect(loginScript).toContain(`-Tenant '${INJECT_ESCAPED}'`); + expect(loginScript).toContain(`-Subscription '${INJECT_ESCAPED}'`); + expect(loginScript).not.toContain(`-Tenant '${INJECT_RAW}'`); + expect(loginScript).not.toContain(`-Subscription '${INJECT_RAW}'`); + }); + }); + + test('SECURITY: resourceManagerEndpointUrl single quote is escaped (AzureStack path)', () => { + setEnv('environment', 'azurestack'); + setEnv('enable-AzPSSession', 'true'); + setEnv('allow-no-subscriptions', 'true'); + setEnv('auth-type', 'SERVICE_PRINCIPAL'); + let creds = { + 'clientId': 'client-id', + 'clientSecret': 'client-secret', + 'tenantId': 'tenant-id', + 'subscriptionId': 'subscription-id', + 'resourceManagerEndpointUrl': INJECT_RAW + } + setEnv('creds', JSON.stringify(creds)); + + let loginConfig = new LoginConfig(); + loginConfig.initialize(); + return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([_, loginScript]) => { + expect(loginScript).toContain(`-ARMEndpoint '${INJECT_ESCAPED}'`); + expect(loginScript).not.toContain(`-ARMEndpoint '${INJECT_RAW}'`); + }); + }); + + test('SECURITY: escapePSSingleQuoted handles null/undefined without throwing', () => { + setEnv('environment', 'azurecloud'); + setEnv('enable-AzPSSession', 'true'); + setEnv('allow-no-subscriptions', 'false'); + setEnv('auth-type', 'IDENTITY'); + + let loginConfig = new LoginConfig(); + loginConfig.initialize(); + return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => { + expect(loginScript).toContain("Connect-AzAccount -Identity -Environment 'azurecloud'"); + expect(loginMethod).toBe('system-assigned managed identity'); + }); + }); + }); \ No newline at end of file diff --git a/src/PowerShell/AzPSScriptBuilder.ts b/src/PowerShell/AzPSScriptBuilder.ts index 5cd34580f..8b6b05824 100644 --- a/src/PowerShell/AzPSScriptBuilder.ts +++ b/src/PowerShell/AzPSScriptBuilder.ts @@ -21,12 +21,20 @@ export default class AzPSScriptBuilder { return script; } + // Doubles single quotes for safe interpolation into a PowerShell '...' literal. + private static escapePSSingleQuoted(value: string): string { + if (value === null || value === undefined) { + return ""; + } + return String(value).split("'").join("''"); + } + static async getAzPSLoginScript(loginConfig: LoginConfig) { let loginMethodName = ""; let commands = ""; if (loginConfig.environment.toLowerCase() == "azurestack") { - commands += `Add-AzEnvironment -Name '${loginConfig.environment}' -ARMEndpoint '${loginConfig.resourceManagerEndpointUrl}' | out-null;`; + commands += `Add-AzEnvironment -Name '${loginConfig.environment}' -ARMEndpoint '${AzPSScriptBuilder.escapePSSingleQuoted(loginConfig.resourceManagerEndpointUrl)}' | out-null;`; } if (loginConfig.authType === LoginConfig.AUTH_TYPE_SERVICE_PRINCIPAL) { if (loginConfig.servicePrincipalSecret) { @@ -64,10 +72,11 @@ export default class AzPSScriptBuilder { } private static loginWithSecret(loginConfig: LoginConfig): string { - let servicePrincipalSecret: string = loginConfig.servicePrincipalSecret.split("'").join("''"); + let servicePrincipalSecret: string = AzPSScriptBuilder.escapePSSingleQuoted(loginConfig.servicePrincipalSecret); + let servicePrincipalId: string = AzPSScriptBuilder.escapePSSingleQuoted(loginConfig.servicePrincipalId); let loginCmdlet = `$psLoginSecrets = ConvertTo-SecureString '${servicePrincipalSecret}' -AsPlainText -Force; `; - loginCmdlet += `$psLoginCredential = New-Object System.Management.Automation.PSCredential('${loginConfig.servicePrincipalId}', $psLoginSecrets); `; - + loginCmdlet += `$psLoginCredential = New-Object System.Management.Automation.PSCredential('${servicePrincipalId}', $psLoginSecrets); `; + let cmdletSuffix = "-Credential $psLoginCredential"; loginCmdlet += AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix); @@ -76,7 +85,9 @@ export default class AzPSScriptBuilder { private static async loginWithOIDC(loginConfig: LoginConfig) { await loginConfig.getFederatedToken(); - let cmdletSuffix = `-ApplicationId '${loginConfig.servicePrincipalId}' -FederatedToken '${loginConfig.federatedToken}'`; + let servicePrincipalId: string = AzPSScriptBuilder.escapePSSingleQuoted(loginConfig.servicePrincipalId); + let federatedToken: string = AzPSScriptBuilder.escapePSSingleQuoted(loginConfig.federatedToken); + let cmdletSuffix = `-ApplicationId '${servicePrincipalId}' -FederatedToken '${federatedToken}'`; return AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix); } @@ -86,7 +97,8 @@ export default class AzPSScriptBuilder { } static loginWithUserAssignedIdentity(loginConfig: LoginConfig): string { - let cmdletSuffix = `-AccountId '${loginConfig.servicePrincipalId}'`; + let servicePrincipalId: string = AzPSScriptBuilder.escapePSSingleQuoted(loginConfig.servicePrincipalId); + let cmdletSuffix = `-AccountId '${servicePrincipalId}'`; return AzPSScriptBuilder.psLoginCmdlet(loginConfig.authType, loginConfig.environment, loginConfig.tenantId, loginConfig.subscriptionId, cmdletSuffix); } @@ -99,10 +111,10 @@ export default class AzPSScriptBuilder { } loginCmdlet += `-Environment '${environment}' `; if(tenantId){ - loginCmdlet += `-Tenant '${tenantId}' `; + loginCmdlet += `-Tenant '${AzPSScriptBuilder.escapePSSingleQuoted(tenantId)}' `; } if(subscriptionId){ - loginCmdlet += `-Subscription '${subscriptionId}' `; + loginCmdlet += `-Subscription '${AzPSScriptBuilder.escapePSSingleQuoted(subscriptionId)}' `; } loginCmdlet += `${cmdletSuffix} -InformationAction Ignore | out-null;`; return loginCmdlet; From e8cd11fea4cc0b12960fe5037c622ad3fba5701c Mon Sep 17 00:00:00 2001 From: Yeming Liu <11371776+isra-fel@users.noreply.github.com> Date: Tue, 4 Aug 2026 12:02:33 +1000 Subject: [PATCH 07/11] Replacing hardcoded version v2 with v3 (#603) --- src/common/Utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/Utils.ts b/src/common/Utils.ts index 8e9186d32..8d36b3cd7 100644 --- a/src/common/Utils.ts +++ b/src/common/Utils.ts @@ -7,8 +7,8 @@ import { AzPSConstants, AzPSUtils } from '../PowerShell/AzPSUtils'; export function setUserAgent(): void { let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex'); let actionName = 'AzureLogin'; - process.env.AZURE_HTTP_USER_AGENT = (!!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT} ` : '') + `GITHUBACTIONS/${actionName}@v2_${usrAgentRepo}_${process.env.RUNNER_ENVIRONMENT}_${process.env.GITHUB_RUN_ID}`; - process.env.AZUREPS_HOST_ENVIRONMENT = (!!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT} ` : '') + `GITHUBACTIONS/${actionName}@v2_${usrAgentRepo}_${process.env.RUNNER_ENVIRONMENT}_${process.env.GITHUB_RUN_ID}`; + process.env.AZURE_HTTP_USER_AGENT = (!!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT} ` : '') + `GITHUBACTIONS/${actionName}@v3_${usrAgentRepo}_${process.env.RUNNER_ENVIRONMENT}_${process.env.GITHUB_RUN_ID}`; + process.env.AZUREPS_HOST_ENVIRONMENT = (!!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT} ` : '') + `GITHUBACTIONS/${actionName}@v3_${usrAgentRepo}_${process.env.RUNNER_ENVIRONMENT}_${process.env.GITHUB_RUN_ID}`; } export async function cleanupAzCLIAccounts(): Promise { From 833e82333ca8452a40084fee403f7f16e65cba70 Mon Sep 17 00:00:00 2001 From: Alex Wang Date: Tue, 4 Aug 2026 16:25:54 -0700 Subject: [PATCH 08/11] Add version support policy guidance (#604) --- README.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a031ca763..5d3085cfb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@ # Azure Login Action - [Azure Login Action](#azure-login-action) + - [Supported Versions](#supported-versions) + - [Version Selection](#version-selection) + - [Major-version tag](#major-version-tag) + - [Exact version tag](#exact-version-tag) + - [Branch reference](#branch-reference) + - [Commit SHA](#commit-sha) + - [Security Updates](#security-updates) - [Input Parameters](#input-parameters) - [`client-id`](#client-id) - [`subscription-id`](#subscription-id) @@ -48,6 +55,70 @@ Azure Login Action supports different ways of authentication with Azure. > [!WARNING] > Avoid using managed identity login on self-hosted runners in public repositories. Managed identities enable secure authentication with Azure resources and obtain Microsoft Entra ID tokens without the need for explicit credential management. Any user can open pull requests against your repository and access your self-hosted runners without credentials. See more details in [self-hosted runner security](https://docs.github.com/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#self-hosted-runner-security). +## Supported Versions + +Azure Login follows a major-version support model. + +| Version | Status | +| --- | --- | +| v3 | Supported | +| v2 | Maintenance mode (security fixes only) | +| v1 | End of Life (EOL) | + +New features are released only to supported versions. Security fixes are released to supported versions and versions in maintenance mode. + +Customers are strongly encouraged to use the latest v3 release. + +## Version Selection + +GitHub Actions users can reference Azure Login using several forms. + +### Major-version tag + +```yaml +uses: azure/login@v3 +``` + +Receives compatible updates, including security fixes, released to the referenced major version. + +### Exact version tag + +```yaml +uses: azure/login@v2.4.0 +``` + +Remains pinned to that specific release and does not automatically receive future fixes or updates. + +### Branch reference + +```yaml +uses: azure/login@master +``` + +Receives updates from the referenced branch. For stable workflows, use a supported major-version tag or pin to a full-length commit SHA. + +### Commit SHA + +```yaml +uses: azure/login@ +``` + +Remains pinned to that commit and does not automatically receive future fixes or updates. + +## Security Updates + +Security fixes are released to supported versions and versions in maintenance mode. Customers using exact version tags or commit SHA references must explicitly upgrade to a patched release to receive security fixes. + +```yaml +# Automatically receives future v3 security updates +uses: azure/login@v3 + +# Does not automatically receive future updates +uses: azure/login@v2.4.0 +``` + +Customers using v1 should migrate to v3. End-of-life releases no longer receive updates or security fixes. + ## Input Parameters |Parameter Name|Required?|Type|Default Value|Description| @@ -705,4 +776,4 @@ provided by the bot. You will only need to do this once across all repos using o This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. From 6f2890194523a5c36c11358f0b293c86d2fdc62b Mon Sep 17 00:00:00 2001 From: MaddyMicrosoft Date: Mon, 17 Aug 2026 13:18:30 +1000 Subject: [PATCH 09/11] Workflows/ci hygiene (#609) * Update azure/login pin from v1 to v3 in canary and integration tests The canary and integration-test workflows still pinned azure/login@v1 while the action is on v3, so they were validating a two-major-old release instead of the current one. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove unused Slack notification jobs from canary and integration tests The slack-post-result jobs posted to a Slack webhook that is no longer used, and referenced a secret with broken interpolation. Removing them; the test jobs themselves are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove redundant pr-check workflow pr-check.yml duplicated ci.yml's build+test (ci.yml already runs on master PRs across windows and ubuntu). Removing the redundant workflow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Run positive/negative live tests on pull requests instead of every push These suites perform real Azure logins. Triggering on every push to any branch ran the full matrix (and consumed live credentials) for incidental commits. Switch to pull_request targeting master, keeping workflow_dispatch for manual runs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Self-provision RG for live login tests; drop VM assertions - positive/negative: add setup/teardown jobs that create and delete GitHubAction_CI_Group via azure/login@v3 (stable), gated on all jobs - drop az vm list / Get-AzVM assertions (no VM is provisioned) - negative permission tests keep targeting the never-created GitHubAction_CI_RG so they fail as expected - shared concurrency group so positive/negative don't collide on the RG * Merge positive/negative live tests into one self-provisioning workflow Replace azure-login-positive.yml and azure-login-negative.yml with a single azure-login-live-tests.yml. All 49 positive and 45 negative test steps are preserved unchanged; only structure and provisioning change. --------- Co-authored-by: Maddison Das <272712104+MaddyMicrosoft@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/azure-login-canary.yml | 29 +- .../azure-login-integration-tests.yml | 39 +- .github/workflows/azure-login-live-tests.yml | 690 ++++++++++++++++++ .github/workflows/azure-login-negative.yml | 335 --------- .github/workflows/azure-login-positive.yml | 316 -------- .github/workflows/azure-login-pr-check.yml | 31 - 6 files changed, 702 insertions(+), 738 deletions(-) create mode 100644 .github/workflows/azure-login-live-tests.yml delete mode 100644 .github/workflows/azure-login-negative.yml delete mode 100644 .github/workflows/azure-login-positive.yml delete mode 100644 .github/workflows/azure-login-pr-check.yml diff --git a/.github/workflows/azure-login-canary.yml b/.github/workflows/azure-login-canary.yml index eb4ef84de..665e04432 100644 --- a/.github/workflows/azure-login-canary.yml +++ b/.github/workflows/azure-login-canary.yml @@ -33,7 +33,7 @@ jobs: uses: actions/checkout@v6 - name: 'Az CLI login with subscription' - uses: azure/login@v1 + uses: azure/login@v3 with: creds: ${{ secrets.AZURE_CREDENTIALS }} @@ -41,7 +41,7 @@ jobs: az account show --output none - name: 'Az CLI login without subscription' - uses: azure/login@v1 + uses: azure/login@v3 with: creds: ${{ secrets.AZURE_CREDENTIALS }} allow-no-subscriptions: true @@ -50,7 +50,7 @@ jobs: az account show --output none - name: 'Az CLI login with subscription OIDC' - uses: azure/login@v1 + uses: azure/login@v3 with: client-id: ${{ secrets.AZURE_CLIENTID }} tenant-id: ${{ secrets.AZURE_TENANTID }} @@ -60,7 +60,7 @@ jobs: az account show --output none - name: 'Az CLI login without subscription OIDC' - uses: azure/login@v1 + uses: azure/login@v3 with: client-id: ${{ secrets.AZURE_CLIENTID }} tenant-id: ${{ secrets.AZURE_TENANTID }} @@ -68,24 +68,3 @@ jobs: - run: | az account show --output none - - slack-post-result: - runs-on: ubuntu-latest -# continue-on-error: true - if: ${{ always() }} - needs: [az-login-test] - steps: - - name: Create slack post - id: slack_report - run: | - TITLE="Login action canary tests update - " - DATEVAR=`date "+%d/%m/%YT%H:%M:%S"` - TITLE="${TITLE}${DATEVAR}" - REPORT="${TITLE}\r\nLink to run - https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\r\n" - RUN_URL="https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" - REPORT="${REPORT}\r\n" - if [ ${{needs.az-login-test.result}} == 'success' ]; then REPORT="${REPORT}\r\n|✅|<${RUN_URL}|az-login-test>"; else REPORT="${REPORT}\r\n|❌|<${RUN_URL}|az-login-test>"; fi - echo "report=$REPORT" >> $GITHUB_OUTPUT - - name: Post to slack - shell: bash - run: curl -X POST -H 'Content-type:application/json' --data '{"blocks":[{"type":"section","text":{"type":"mrkdwn","text":"${{steps.slack_report.outputs.report}}"}}]}' https://hooks.slack.com/services/${{SECRETS.SLACK_CHANNEL_SECRET}} diff --git a/.github/workflows/azure-login-integration-tests.yml b/.github/workflows/azure-login-integration-tests.yml index a746e74f0..31b91186e 100644 --- a/.github/workflows/azure-login-integration-tests.yml +++ b/.github/workflows/azure-login-integration-tests.yml @@ -14,7 +14,7 @@ jobs: # continue-on-error: true steps: - name: 'Az CLI login with subscription' - uses: azure/login@v1 + uses: azure/login@v3 with: creds: ${{ secrets.AZURE_CREDENTIALS }} @@ -23,7 +23,7 @@ jobs: az vm list --output none - name: 'Az CLI login without subscription' - uses: azure/login@v1 + uses: azure/login@v3 with: creds: ${{ secrets.AZURE_CREDENTIALS }} allow-no-subscriptions: true @@ -32,7 +32,7 @@ jobs: az account show --output none - name: 'Azure PowerShell login with subscription' - uses: azure/login@v1 + uses: azure/login@v3 with: creds: ${{ secrets.AZURE_CREDENTIALS }} enable-AzPSSession: true @@ -43,7 +43,7 @@ jobs: azPSVersion: "latest" - name: 'Azure PowerShell login without subscription' - uses: azure/login@v1 + uses: azure/login@v3 with: creds: ${{secrets.AZURE_CREDENTIALS}} enable-AzPSSession: true @@ -59,7 +59,7 @@ jobs: # continue-on-error: true steps: - name: 'Az CLI login with subscription' - uses: azure/login@v1 + uses: azure/login@v3 with: client-id: ${{ secrets.AZURE_CLIENTID }} tenant-id: ${{ secrets.AZURE_TENANTID }} @@ -70,7 +70,7 @@ jobs: az vm list --output none - name: 'Az CLI login without subscription' - uses: azure/login@v1 + uses: azure/login@v3 with: client-id: ${{ secrets.AZURE_CLIENTID }} tenant-id: ${{ secrets.AZURE_TENANTID }} @@ -80,7 +80,7 @@ jobs: az account show --output none - name: 'Azure PowerShell login with subscription' - uses: azure/login@v1 + uses: azure/login@v3 with: client-id: ${{ secrets.AZURE_CLIENTID }} tenant-id: ${{ secrets.AZURE_TENANTID }} @@ -93,7 +93,7 @@ jobs: azPSVersion: "latest" - name: 'Azure PowerShell login without subscription' - uses: azure/login@v1 + uses: azure/login@v3 with: client-id: ${{ secrets.AZURE_CLIENTID }} tenant-id: ${{ secrets.AZURE_TENANTID }} @@ -104,26 +104,3 @@ jobs: with: inlineScript: "(Get-AzContext).Environment.Name" azPSVersion: "latest" - - slack-post-result: - runs-on: ubuntu-latest -# continue-on-error: true - if: ${{ always() }} - needs: [az-login-test-non-oidc, az-login-test-oidc] - steps: - - name: Create slack post - id: slack_report - run: | - TITLE="Login action OIDC flow tests update - " - DATEVAR=`date "+%d/%m/%YT%H:%M:%S"` - TITLE="${TITLE}${DATEVAR}" - REPORT="${TITLE}\r\nLink to run - https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\r\n" - RUN_URL="https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" - REPORT="${REPORT}\r\n" - if [ ${{needs.az-login-test-non-oidc.result}} == 'success' ]; then REPORT="${REPORT}\r\n|✅|<${RUN_URL}|az-login-test-non-oidc>"; else REPORT="${REPORT}\r\n|❌|<${RUN_URL}|az-login-test-non-oidc>"; fi - if [ ${{needs.az-login-test-oidc.result}} == 'success' ]; then REPORT="${REPORT}\r\n|✅|<${RUN_URL}|az-login-test-oidc>"; else REPORT="${REPORT}\r\n|❌|<${RUN_URL}|az-login-test-oidc>"; fi - echo "report=$REPORT" >> $GITHUB_OUTPUT - - - name: Post to slack - shell: bash - run: curl -X POST -H 'Content-type:application/json' --data '{"blocks":[{"type":"section","text":{"type":"mrkdwn","text":"${{steps.slack_report.outputs.report}}"}}]}' https://hooks.slack.com/services/${{SECRETS.SLACK_CHANNEL_SECRET}} diff --git a/.github/workflows/azure-login-live-tests.yml b/.github/workflows/azure-login-live-tests.yml new file mode 100644 index 000000000..ec872ff77 --- /dev/null +++ b/.github/workflows/azure-login-live-tests.yml @@ -0,0 +1,690 @@ +name: Azure Login Action Live Tests +on: + workflow_dispatch: + pull_request: + branches: + - master + +permissions: + id-token: write + contents: read + +# One resource group is shared by every job in this run, so serialize runs to +# avoid one run tearing down another's group. +concurrency: + group: azure-login-live-tests + cancel-in-progress: false + +env: + # Created once in setup; the positive and embedded "can access" assertions + # target this group. + RG_POSITIVE: GitHubAction_CI_Group + LOCATION: eastus + # Intentionally NEVER created: the negative permission/not-found assertions + # target this name so they fail as expected. + RG_NEGATIVE: GitHubAction_CI_RG + +jobs: + # ---------------------------------------------------------------- setup + # Provision the resource group the "can access" assertions target. Uses a + # repo-level provisioning credential (PROVISION_CREDS) and does NOT declare an + # environment, so it is not subject to the Automation test approval gate - + # setup/teardown are provisioning, not part of the gated test surface. + setup: + runs-on: ubuntu-latest + steps: + - name: Azure login (provisioning) + uses: azure/login@v3 + with: + creds: ${{ secrets.PROVISION_CREDS }} + - name: Create resource group + run: az group create --name "$RG_POSITIVE" --location "$LOCATION" --output none + + # ================================================================ POSITIVE + Positive_BasicTest: + needs: setup + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} + environment: Automation test + + steps: + - name: 'Checking out repo code' + uses: actions/checkout@v6 + + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 + with: + node-version: 24.x + + - name: 'Validate build' + run: | + npm install + npm run build + + - name: 'Run L0 tests' + run: | + npm run test + + - name: Login with creds + uses: ./ + with: + creds: ${{secrets.SP1}} + enable-AzPSSession: true + + - name: Run Azure Cli + run: | + az account show --output none + az group show --name GitHubAction_CI_Group --output none + + - name: Run Azure PowerShell + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' + if(-not $checkResult){ + throw "Not all checks passed!" + } + + - name: Login with individual parameters + uses: ./ + with: + client-id: ${{ secrets.SP1_CLIENT_ID }} + tenant-id: ${{ secrets.SP1_TENANT_ID }} + subscription-id: ${{ secrets.SP1_SUBSCRIPTION_ID }} + enable-AzPSSession: true + + - name: Run Azure Cli again + run: | + az account show --output none + + - name: Run Azure PowerShell again + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' + if(-not $checkResult){ + throw "Not all checks passed!" + } + + - name: Login with explicit auth-type + uses: ./ + with: + creds: ${{secrets.SP1}} + auth-type: SERVICE_PRINCIPAL + enable-AzPSSession: true + + - name: Run Azure Cli + run: | + az account show --output none + az group show --name GitHubAction_CI_Group --output none + + - name: Run Azure PowerShell + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' + if(-not $checkResult){ + throw "Not all checks passed!" + } + + Positive_ParameterTest: + needs: setup + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} + environment: Automation test + + steps: + - name: 'Checking out repo code' + uses: actions/checkout@v6 + + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 + with: + node-version: 24.x + + - name: 'Validate build' + run: | + npm install + npm run build + + - name: Login with creds, disable ps session + uses: ./ + with: + creds: ${{secrets.SP1}} + enable-AzPSSession: false + + - name: Run Azure Cli + run: | + az account show --output none + az group show --name GitHubAction_CI_Group --output none + + - name: Login with creds, wrong boolean value + uses: ./ + with: + creds: ${{secrets.SP1}} + enable-AzPSSession: notboolean + + - name: Run Azure Cli + run: | + az account show --output none + az group show --name GitHubAction_CI_Group --output none + + - name: Login with creds, allow no subscription + uses: ./ + with: + creds: ${{secrets.SP1}} + allow-no-subscriptions: true + enable-AzPSSession: true + + - name: Run Azure Cli + run: | + az account show --output none + az group show --name GitHubAction_CI_Group --output none + + - name: Run Azure PowerShell + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' + if(-not $checkResult){ + throw "Not all checks passed!" + } + + - name: Login with individual parameters, allow no subscription + uses: ./ + with: + client-id: ${{ secrets.SP1_CLIENT_ID }} + tenant-id: ${{ secrets.SP1_TENANT_ID}} + subscription-id: ${{ secrets.SP1_SUBSCRIPTION_ID }} + allow-no-subscriptions: true + enable-AzPSSession: true + + - name: Run Azure Cli again + run: | + az account show --output none + + - name: Run Azure PowerShell again + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' + if(-not $checkResult){ + throw "Not all checks passed!" + } + + - name: Login with individual parameters, no subscription, allow no subscription + uses: ./ + with: + client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} + tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} + allow-no-subscriptions: true + enable-AzPSSession: true + + - name: Run Azure Cli + shell: pwsh + run: | + $checkResult = (az account list --output json | ConvertFrom-Json).Count -eq 2 + if(-not $checkResult){ + throw "Not all checks passed!" + } + + - name: Run Azure PowerShell + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' + if(-not $checkResult){ + throw "Not all checks passed!" + } + + - name: Login with creds, no subscription, allow no subscription + uses: ./ + with: + creds: '{"clientId":"${{ secrets.OIDC_SP2_CLIENT_ID }}","clientSecret":"${{ secrets.SP2_CLIENT_SECRET }}","tenantId":"${{ secrets.OIDC_SP2_TENANT_ID }}"}' + allow-no-subscriptions: true + enable-AzPSSession: true + + - name: Run Azure Cli + run: | + az account show --output none + + - name: Run Azure PowerShell + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' + if(-not $checkResult){ + throw "Not all checks passed!" + } + + Positive_InDockerTest: + needs: setup + runs-on: ubuntu-latest + container: ubuntu:24.04 + environment: Automation test + steps: + - name: 'Checking out repo code' + uses: actions/checkout@v6 + + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 + with: + node-version: 24.x + + - name: Install Azure CLI + run: | + apt-get update + apt-get install -y curl + curl -sL https://aka.ms/InstallAzureCLIDeb | bash + + - name: Check Azure CLI Version + run: | + az --version + + - name: Install Powershell + run: | + apt-get update + apt-get install -y wget apt-transport-https software-properties-common + wget -q "https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb" + dpkg -i packages-microsoft-prod.deb + rm packages-microsoft-prod.deb + apt-get update + apt-get install -y powershell + + - name: Check Powershell Version + shell: pwsh + run: | + $PSVersionTable + + - name: Install Azure Powershell + shell: pwsh + run: | + Install-Module -Name Az -Repository PSGallery -Force + + - name: Check Azure Powershell Version + shell: pwsh + run: | + Get-Module -ListAvailable Az + + - name: 'Validate build' + run: | + npm install + npm run build + + - name: 'Run L0 tests' + run: | + npm run test + + - name: Login with individual parameters + uses: ./ + with: + client-id: ${{ secrets.SP1_CLIENT_ID }} + tenant-id: ${{ secrets.SP1_TENANT_ID }} + subscription-id: ${{ secrets.SP1_SUBSCRIPTION_ID }} + enable-AzPSSession: true + + - name: Run Azure Cli again + run: | + az group list --output none + + - name: Run Azure PowerShell again + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + $checkResult = Get-AzResourceGroup + + # ================================================================ NEGATIVE + Negative_PermissionTest: + needs: setup + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} + environment: Automation test + + steps: + + - name: 'Checking out repo code' + uses: actions/checkout@v6 + + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 + with: + node-version: 24.x + + - name: 'Validate build' + run: | + npm install + npm run build + + - name: Login with individual parameters + uses: ./ + with: + client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} + tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} + # subscription-id: ${{ secrets.OIDC_SP2_SUBSCRIPTION_ID }} + allow-no-subscriptions: true + enable-AzPSSession: true + + - name: Run Azure Cli + id: cli_3 + continue-on-error: true + run: | + az account show --output none + az group show --name GitHubAction_CI_RG --output none + + - name: Check Last step failed + if: steps.cli_3.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Run Azure PowerShell + id: ps_3 + continue-on-error: true + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + (Get-AzContext).Environment.Name -eq 'AzureCloud' + (Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG' + + - name: Check Last step failed + if: steps.ps_3.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + Negative_ParameterTest: + needs: setup + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} + environment: Automation test + + steps: + - name: 'Checking out repo code' + uses: actions/checkout@v6 + + - name: Set Node.js 24.x for GitHub Action + uses: actions/setup-node@v6 + with: + node-version: 24.x + + - name: 'Validate build' + run: | + npm install + npm run build + + - name: Login with creds, missing parameters in creds + id: login_4 + continue-on-error: true + uses: ./ + with: + creds: ${{secrets.SP3_NO_Secret}} + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_4.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login with creds, wrong keys + id: login_5 + continue-on-error: true + uses: ./ + with: + creds: ${{secrets.SP4_Wrong_Key}} + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_5.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login with creds, no creds or individual parameters + id: login_6 + continue-on-error: true + uses: ./ + with: + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_6.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login with individual parameters, only client-id, no tenant-id, subscription-id + id: login_7 + continue-on-error: true + uses: ./ + with: + client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} + allow-no-subscriptions: true + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_7.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login with individual parameters, only tenant-id, subscription-id, no client-id + id: login_8 + continue-on-error: true + uses: ./ + with: + tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} + subscription-id: ${{ secrets.OIDC_SP2_SUBSCRIPTION_ID }} + allow-no-subscriptions: true + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_8.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login with creds, disable ps session + uses: ./ + with: + creds: ${{secrets.SP1}} + enable-AzPSSession: false + + - name: Run Azure Cli + run: | + az account show --output none + az group show --name GitHubAction_CI_Group --output none + + - name: Run Azure PowerShell + id: ps_8 + continue-on-error: true + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + (Get-AzContext).Environment.Name -eq 'AzureCloud' + (Get-AzResourceGroup -Name GitHubAction_CI_Group).ResourceGroupName -eq 'GitHubAction_CI_Group' + + - name: Check Last step failed + if: steps.ps_8.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login with creds, wrong boolean value + uses: ./ + with: + creds: ${{secrets.SP1}} + enable-AzPSSession: notboolean + + - name: Run Azure Cli + run: | + az account show --output none + az group show --name GitHubAction_CI_Group --output none + + - name: Run Azure PowerShell + id: ps_9 + continue-on-error: true + uses: azure/powershell@v3 + with: + azPSVersion: "latest" + inlineScript: | + (Get-AzContext).Environment.Name -eq 'AzureCloud' + (Get-AzResourceGroup -Name GitHubAction_CI_Group).ResourceGroupName -eq 'GitHubAction_CI_Group' + + - name: Check Last step failed + if: steps.ps_9.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login with individual parameters, with a wrong audience + id: login_10 + continue-on-error: true + uses: ./ + with: + client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} + tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} + subscription-id: ${{ secrets.OIDC_SP2_SUBSCRIPTION_ID }} + audience: "https://github.com/actions" + allow-no-subscriptions: true + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_10.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login with tenant-level account, without allow-no-subscriptions + id: login_11 + continue-on-error: true + uses: ./ + with: + client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} + tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} + subscription-id: ${{ secrets.OIDC_SP2_SUBSCRIPTION_ID }} + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_11.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + # SP1 is ignored and SP2 will be used for login, but it will fail since SP2 has no access to the given subscription + - name: Login with both creds and individual parameters + id: login_12 + continue-on-error: true + uses: ./ + with: + creds: ${{secrets.SP1}} + client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} + tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} + subscription-id: ${{ secrets.OIDC_SP2_SUBSCRIPTION_ID }} + allow-no-subscriptions: true + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_12.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login by OIDC with all info in creds + id: login_13 + continue-on-error: true + uses: ./ + with: + creds: ${{secrets.SP2}} + allow-no-subscriptions: true + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_13.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login with individual parameters, no subscription-id, no allow-no-subscriptions + id: login_14 + continue-on-error: true + uses: ./ + with: + client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} + tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_14.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + - name: Login with creds, no subscription-id, no allow-no-subscriptions + id: login_15 + continue-on-error: true + uses: ./ + with: + creds: '{"clientId":"${{ secrets.OIDC_SP2_CLIENT_ID }}","clientSecret":"${{ secrets.SP2_CLIENT_SECRET }}","tenantId":"${{ secrets.OIDC_SP2_TENANT_ID }}"}' + enable-AzPSSession: true + + - name: Check Last step failed + if: steps.login_15.outcome == 'success' + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Last action should fail but not. Please check it.') + + # ---------------------------------------------------------------- teardown + # Always delete the resource group created in setup, even if gate jobs failed, + # so nothing is left running (cost) between the infrequent runs. Runs + # synchronously (no --no-wait) so the group is fully gone before the run ends + # and the concurrency lock releases, preventing a delete from a finished run + # racing the setup of the next one. + teardown: + needs: [setup, Positive_BasicTest, Positive_ParameterTest, Positive_InDockerTest, Negative_PermissionTest, Negative_ParameterTest] + if: always() + runs-on: ubuntu-latest + steps: + - name: Azure login (provisioning) + uses: azure/login@v3 + with: + creds: ${{ secrets.PROVISION_CREDS }} + - name: Delete resource group + run: az group delete --name "$RG_POSITIVE" --yes --output none || true diff --git a/.github/workflows/azure-login-negative.yml b/.github/workflows/azure-login-negative.yml deleted file mode 100644 index 37c39faed..000000000 --- a/.github/workflows/azure-login-negative.yml +++ /dev/null @@ -1,335 +0,0 @@ -name: Azure Login Action Negative Test -on: - workflow_dispatch: - push: - -permissions: - id-token: write - contents: read - -jobs: - - PermissionTest: - strategy: - matrix: - os: [ubuntu-latest, windows-latest] - runs-on: ${{ matrix.os }} - environment: Automation test - - steps: - - - name: 'Checking out repo code' - uses: actions/checkout@v6 - - - name: Set Node.js 24.x for GitHub Action - uses: actions/setup-node@v6 - with: - node-version: 24.x - - - name: 'Validate build' - run: | - npm install - npm run build - - - name: Login with individual parameters - uses: ./ - with: - client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} - tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} - # subscription-id: ${{ secrets.OIDC_SP2_SUBSCRIPTION_ID }} - allow-no-subscriptions: true - enable-AzPSSession: true - - - name: Run Azure Cli - id: cli_3 - continue-on-error: true - run: | - az account show --output none - az group show --name GitHubAction_CI_RG --output none - az vm list --output none - - - name: Check Last step failed - if: steps.cli_3.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Run Azure PowerShell - id: ps_3 - continue-on-error: true - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - (Get-AzContext).Environment.Name -eq 'AzureCloud' - (Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG' - (Get-AzVM).Count -gt 0 - - - name: Check Last step failed - if: steps.ps_3.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - ParameterTest: - strategy: - matrix: - os: [ubuntu-latest, windows-latest] - runs-on: ${{ matrix.os }} - environment: Automation test - - steps: - - name: 'Checking out repo code' - uses: actions/checkout@v6 - - - name: Set Node.js 24.x for GitHub Action - uses: actions/setup-node@v6 - with: - node-version: 24.x - - - name: 'Validate build' - run: | - npm install - npm run build - - - name: Login with creds, missing parameters in creds - id: login_4 - continue-on-error: true - uses: ./ - with: - creds: ${{secrets.SP3_NO_Secret}} - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_4.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login with creds, wrong keys - id: login_5 - continue-on-error: true - uses: ./ - with: - creds: ${{secrets.SP4_Wrong_Key}} - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_5.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login with creds, no creds or individual parameters - id: login_6 - continue-on-error: true - uses: ./ - with: - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_6.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login with individual parameters, only client-id, no tenant-id, subscription-id - id: login_7 - continue-on-error: true - uses: ./ - with: - client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} - allow-no-subscriptions: true - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_7.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login with individual parameters, only tenant-id, subscription-id, no client-id - id: login_8 - continue-on-error: true - uses: ./ - with: - tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} - subscription-id: ${{ secrets.OIDC_SP2_SUBSCRIPTION_ID }} - allow-no-subscriptions: true - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_8.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login with creds, disable ps session - uses: ./ - with: - creds: ${{secrets.SP1}} - enable-AzPSSession: false - - - name: Run Azure Cli - run: | - az account show --output none - az group show --name GitHubAction_CI_RG --output none - az vm list --output none - - - name: Run Azure PowerShell - id: ps_8 - continue-on-error: true - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - (Get-AzContext).Environment.Name -eq 'AzureCloud' - (Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG' - (Get-AzVM).Count -gt 0 - - - name: Check Last step failed - if: steps.ps_8.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login with creds, wrong boolean value - uses: ./ - with: - creds: ${{secrets.SP1}} - enable-AzPSSession: notboolean - - - name: Run Azure Cli - run: | - az account show --output none - az group show --name GitHubAction_CI_RG --output none - az vm list --output none - - - name: Run Azure PowerShell - id: ps_9 - continue-on-error: true - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - (Get-AzContext).Environment.Name -eq 'AzureCloud' - (Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG' - (Get-AzVM).Count -gt 0 - - - name: Check Last step failed - if: steps.ps_9.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login with individual parameters, with a wrong audience - id: login_10 - continue-on-error: true - uses: ./ - with: - client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} - tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} - subscription-id: ${{ secrets.OIDC_SP2_SUBSCRIPTION_ID }} - audience: "https://github.com/actions" - allow-no-subscriptions: true - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_10.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login with tenant-level account, without allow-no-subscriptions - id: login_11 - continue-on-error: true - uses: ./ - with: - client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} - tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} - subscription-id: ${{ secrets.OIDC_SP2_SUBSCRIPTION_ID }} - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_11.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - # SP1 is ignored and SP2 will be used for login, but it will fail since SP2 has no access to the given subscription - - name: Login with both creds and individual parameters - id: login_12 - continue-on-error: true - uses: ./ - with: - creds: ${{secrets.SP1}} - client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} - tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} - subscription-id: ${{ secrets.OIDC_SP2_SUBSCRIPTION_ID }} - allow-no-subscriptions: true - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_12.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login by OIDC with all info in creds - id: login_13 - continue-on-error: true - uses: ./ - with: - creds: ${{secrets.SP2}} - allow-no-subscriptions: true - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_13.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login with individual parameters, no subscription-id, no allow-no-subscriptions - id: login_14 - continue-on-error: true - uses: ./ - with: - client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} - tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_14.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') - - - name: Login with creds, no subscription-id, no allow-no-subscriptions - id: login_15 - continue-on-error: true - uses: ./ - with: - creds: '{"clientId":"${{ secrets.OIDC_SP2_CLIENT_ID }}","clientSecret":"${{ secrets.SP2_CLIENT_SECRET }}","tenantId":"${{ secrets.OIDC_SP2_TENANT_ID }}"}' - enable-AzPSSession: true - - - name: Check Last step failed - if: steps.login_15.outcome == 'success' - uses: actions/github-script@v7 - with: - script: | - core.setFailed('Last action should fail but not. Please check it.') diff --git a/.github/workflows/azure-login-positive.yml b/.github/workflows/azure-login-positive.yml deleted file mode 100644 index 340d3b828..000000000 --- a/.github/workflows/azure-login-positive.yml +++ /dev/null @@ -1,316 +0,0 @@ -name: Azure Login Action Positive Test -on: - workflow_dispatch: - push: - -permissions: - id-token: write - contents: read - -jobs: - - BasicTest: - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - runs-on: ${{ matrix.os }} - environment: Automation test - - steps: - - name: 'Checking out repo code' - uses: actions/checkout@v6 - - - name: Set Node.js 24.x for GitHub Action - uses: actions/setup-node@v6 - with: - node-version: 24.x - - - name: 'Validate build' - run: | - npm install - npm run build - - - name: 'Run L0 tests' - run: | - npm run test - - - name: Login with creds - uses: ./ - with: - creds: ${{secrets.SP1}} - enable-AzPSSession: true - - - name: Run Azure Cli - run: | - az account show --output none - az group show --name GitHubAction_CI_RG --output none - az vm list --output none - - - name: Run Azure PowerShell - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' - if(-not $checkResult){ - throw "Not all checks passed!" - } - - - name: Login with individual parameters - uses: ./ - with: - client-id: ${{ secrets.SP1_CLIENT_ID }} - tenant-id: ${{ secrets.SP1_TENANT_ID }} - subscription-id: ${{ secrets.SP1_SUBSCRIPTION_ID }} - enable-AzPSSession: true - - - name: Run Azure Cli again - run: | - az account show --output none - - - name: Run Azure PowerShell again - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' - if(-not $checkResult){ - throw "Not all checks passed!" - } - - - name: Login with explicit auth-type - uses: ./ - with: - creds: ${{secrets.SP1}} - auth-type: SERVICE_PRINCIPAL - enable-AzPSSession: true - - - name: Run Azure Cli - run: | - az account show --output none - az group show --name GitHubAction_CI_RG --output none - az vm list --output none - - - name: Run Azure PowerShell - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' - if(-not $checkResult){ - throw "Not all checks passed!" - } - - ParameterTest: - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - runs-on: ${{ matrix.os }} - environment: Automation test - - steps: - - name: 'Checking out repo code' - uses: actions/checkout@v6 - - - name: Set Node.js 24.x for GitHub Action - uses: actions/setup-node@v6 - with: - node-version: 24.x - - - name: 'Validate build' - run: | - npm install - npm run build - - - name: Login with creds, disable ps session - uses: ./ - with: - creds: ${{secrets.SP1}} - enable-AzPSSession: false - - - name: Run Azure Cli - run: | - az account show --output none - az group show --name GitHubAction_CI_RG --output none - az vm list --output none - - - name: Login with creds, wrong boolean value - uses: ./ - with: - creds: ${{secrets.SP1}} - enable-AzPSSession: notboolean - - - name: Run Azure Cli - run: | - az account show --output none - az group show --name GitHubAction_CI_RG --output none - az vm list --output none - - - name: Login with creds, allow no subscription - uses: ./ - with: - creds: ${{secrets.SP1}} - allow-no-subscriptions: true - enable-AzPSSession: true - - - name: Run Azure Cli - run: | - az account show --output none - az group show --name GitHubAction_CI_RG --output none - az vm list --output none - - - name: Run Azure PowerShell - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' - if(-not $checkResult){ - throw "Not all checks passed!" - } - - - name: Login with individual parameters, allow no subscription - uses: ./ - with: - client-id: ${{ secrets.SP1_CLIENT_ID }} - tenant-id: ${{ secrets.SP1_TENANT_ID}} - subscription-id: ${{ secrets.SP1_SUBSCRIPTION_ID }} - allow-no-subscriptions: true - enable-AzPSSession: true - - - name: Run Azure Cli again - run: | - az account show --output none - - - name: Run Azure PowerShell again - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' - if(-not $checkResult){ - throw "Not all checks passed!" - } - - - name: Login with individual parameters, no subscription, allow no subscription - uses: ./ - with: - client-id: ${{ secrets.OIDC_SP2_CLIENT_ID }} - tenant-id: ${{ secrets.OIDC_SP2_TENANT_ID }} - allow-no-subscriptions: true - enable-AzPSSession: true - - - name: Run Azure Cli - shell: pwsh - run: | - $checkResult = (az account list --output json | ConvertFrom-Json).Count -eq 2 - if(-not $checkResult){ - throw "Not all checks passed!" - } - - - name: Run Azure PowerShell - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' - if(-not $checkResult){ - throw "Not all checks passed!" - } - - - name: Login with creds, no subscription, allow no subscription - uses: ./ - with: - creds: '{"clientId":"${{ secrets.OIDC_SP2_CLIENT_ID }}","clientSecret":"${{ secrets.SP2_CLIENT_SECRET }}","tenantId":"${{ secrets.OIDC_SP2_TENANT_ID }}"}' - allow-no-subscriptions: true - enable-AzPSSession: true - - - name: Run Azure Cli - run: | - az account show --output none - - - name: Run Azure PowerShell - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - $checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud' - if(-not $checkResult){ - throw "Not all checks passed!" - } - - InDockerTest: - runs-on: ubuntu-latest - container: ubuntu:24.04 - environment: Automation test - steps: - - name: 'Checking out repo code' - uses: actions/checkout@v6 - - - name: Set Node.js 24.x for GitHub Action - uses: actions/setup-node@v6 - with: - node-version: 24.x - - - name: Install Azure CLI - run: | - apt-get update - apt-get install -y curl - curl -sL https://aka.ms/InstallAzureCLIDeb | bash - - - name: Check Azure CLI Version - run: | - az --version - - - name: Install Powershell - run: | - apt-get update - apt-get install -y wget apt-transport-https software-properties-common - wget -q "https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb" - dpkg -i packages-microsoft-prod.deb - rm packages-microsoft-prod.deb - apt-get update - apt-get install -y powershell - - - name: Check Powershell Version - shell: pwsh - run: | - $PSVersionTable - - - name: Install Azure Powershell - shell: pwsh - run: | - Install-Module -Name Az -Repository PSGallery -Force - - - name: Check Azure Powershell Version - shell: pwsh - run: | - Get-Module -ListAvailable Az - - - name: 'Validate build' - run: | - npm install - npm run build - - - name: 'Run L0 tests' - run: | - npm run test - - - name: Login with individual parameters - uses: ./ - with: - client-id: ${{ secrets.SP1_CLIENT_ID }} - tenant-id: ${{ secrets.SP1_TENANT_ID }} - subscription-id: ${{ secrets.SP1_SUBSCRIPTION_ID }} - enable-AzPSSession: true - - - name: Run Azure Cli again - run: | - az group list --output none - - - name: Run Azure PowerShell again - uses: azure/powershell@v3 - with: - azPSVersion: "latest" - inlineScript: | - $checkResult = Get-AzResourceGroup diff --git a/.github/workflows/azure-login-pr-check.yml b/.github/workflows/azure-login-pr-check.yml deleted file mode 100644 index b0cf457b9..000000000 --- a/.github/workflows/azure-login-pr-check.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: pr-check - -on: - pull_request: - branches: - - master - - 'releases/*' -jobs: - az-login-test: - runs-on: windows-latest - steps: - - name: Checkout from PR branch - uses: actions/checkout@v6 - with: - repository: ${{ github.event.pull_request.head.repo.full_name }} - ref: ${{ github.event.pull_request.head.ref }} - - # Using 24.x version as an example - - name: Set Node.js 24.x for GitHub Action - uses: actions/setup-node@v6 - with: - node-version: 24.x - - - name: installing node_modules - run: npm install - - - name: Build GitHub Action - run: npm run build - - - name: Run mock test - run: npm run test From 32b477179f51f55c6556bbc3c5f24205e8419e05 Mon Sep 17 00:00:00 2001 From: MaddyMicrosoft Date: Mon, 17 Aug 2026 15:37:10 +1000 Subject: [PATCH 10/11] Cleanup/package json and dependabot (#608) * Remove accidental package-lock dependency Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove unused version field from package.json Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Dependabot config (npm + github-actions) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Maddison Das <272712104+MaddyMicrosoft@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/dependabot.yml | 19 ++++++++++++++ package-lock.json | 56 +++++++++--------------------------------- package.json | 4 +-- 3 files changed, 32 insertions(+), 47 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..b545d1322 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,19 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 5 + groups: + dev-dependencies: + dependency-type: "development" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 5 + groups: + github-actions: + patterns: ["*"] diff --git a/package-lock.json b/package-lock.json index a0c620929..6e981114d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,13 +6,11 @@ "packages": { "": { "name": "login", - "version": "3.0.0", "license": "MIT", "dependencies": { "@actions/core": "1.9.1", "@actions/exec": "^1.0.1", - "@actions/io": "^1.0.1", - "package-lock": "^1.0.3" + "@actions/io": "^1.0.1" }, "devDependencies": { "@types/jest": "^29.2.4", @@ -1065,13 +1063,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/asyncc": { - "version": "2.0.6", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/babel-jest": { "version": "29.3.1", "dev": true, @@ -1160,12 +1151,14 @@ }, "node_modules/balanced-match": { "version": "1.0.2", + "dev": true, "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -1346,15 +1339,9 @@ "dev": true, "license": "MIT" }, - "node_modules/commander": { - "version": "5.1.0", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/concat-map": { "version": "0.0.1", + "dev": true, "license": "MIT" }, "node_modules/convert-source-map": { @@ -1563,6 +1550,7 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", + "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -1622,6 +1610,7 @@ }, "node_modules/glob": { "version": "7.2.3", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -1703,6 +1692,7 @@ }, "node_modules/inflight": { "version": "1.0.6", + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -1711,6 +1701,7 @@ }, "node_modules/inherits": { "version": "2.0.4", + "dev": true, "license": "ISC" }, "node_modules/is-arrayish": { @@ -2464,12 +2455,6 @@ "node": ">=8" } }, - "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", - "license": "MIT" - }, "node_modules/lodash.memoize": { "version": "4.1.2", "dev": true, @@ -2544,6 +2529,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -2593,6 +2579,7 @@ }, "node_modules/once": { "version": "1.4.0", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -2659,20 +2646,6 @@ "node": ">=6" } }, - "node_modules/package-lock": { - "version": "1.0.3", - "license": "Unlicense", - "dependencies": { - "asyncc": "^2.0.4", - "commander": "^5.0.0", - "glob": "^7.1.6", - "lodash": "^4.17.15", - "traverse": "^0.6.6" - }, - "bin": { - "package-lock": "bin/package-lock.js" - } - }, "node_modules/parse-json": { "version": "5.2.0", "dev": true, @@ -2700,6 +2673,7 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3050,13 +3024,6 @@ "node": ">=8.0" } }, - "node_modules/traverse": { - "version": "0.6.7", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/ts-jest": { "version": "29.0.3", "dev": true, @@ -3234,6 +3201,7 @@ }, "node_modules/wrappy": { "version": "1.0.2", + "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { diff --git a/package.json b/package.json index c1bb09287..6364c76cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,5 @@ { "name": "login", - "version": "3.0.0", "description": "Login Azure wraps the az login, allowing for Azure actions to log into Azure", "main": "lib/main/index.js", "scripts": { @@ -23,7 +22,6 @@ "dependencies": { "@actions/core": "1.9.1", "@actions/exec": "^1.0.1", - "@actions/io": "^1.0.1", - "package-lock": "^1.0.3" + "@actions/io": "^1.0.1" } } From 3b64cbda39d4a423951ec87e69bcb45ec37bb851 Mon Sep 17 00:00:00 2001 From: MaddyMicrosoft Date: Tue, 18 Aug 2026 12:45:53 +1000 Subject: [PATCH 11/11] Add in dynamic version for telemetry using GITHUB_ACTION_REF (#614) * Add in dynamic version for telemetry using GITHUB_ACTION_REF * Isolate live-test resource group per run; scope concurrency to the branch The live-tests workflow used a fixed resource group name (GitHubAction_CI_Group) plus a repo-wide concurrency group. Because the test jobs run behind the Automation test approval gate, an unapproved run sits in the 'waiting' state holding the shared concurrency lock, which blocked live-tests on every other PR indefinitely. Give each run its own resource group by suffixing the name with github.run_id, and reference it via the RG_POSITIVE env var everywhere (previously nine jobs used the literal name). With per-run isolation the repo-wide lock is no longer needed to prevent collisions, so the concurrency group is now scoped to the branch (github.ref) and only prevents pile-ups on rapid pushes to the same ref - never across PRs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix resource group name expansion on Windows runners The per-run resource group name was referenced as the bash-style "$RG_POSITIVE" in az group show/create/delete run steps. Those steps use the runner default shell, which is PowerShell on windows-latest, so the name expanded to an empty string there and az failed with "argument --name/-n/--resource-group/-g: expected one argument". Reference the value through the GitHub Actions env expression instead, so it is substituted before the shell runs, making it shell-agnostic across ubuntu, windows, and macos. The azure/powershell inline scripts keep using the PowerShell env form, which is correct there. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Maddison Das <272712104+MaddyMicrosoft@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/azure-login-live-tests.yml | 35 +++++++++++--------- src/common/Utils.ts | 5 +-- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/.github/workflows/azure-login-live-tests.yml b/.github/workflows/azure-login-live-tests.yml index ec872ff77..1d3657a95 100644 --- a/.github/workflows/azure-login-live-tests.yml +++ b/.github/workflows/azure-login-live-tests.yml @@ -9,16 +9,19 @@ permissions: id-token: write contents: read -# One resource group is shared by every job in this run, so serialize runs to -# avoid one run tearing down another's group. +# Each run provisions its own uniquely-named resource group (suffixed with the +# run id), so concurrent runs on different branches/PRs never collide or tear +# down each other's group. The concurrency group is branch-scoped only to avoid +# piling up runs on rapid pushes to the same ref - it does NOT serialize across +# the whole repo, so an unapproved run on one PR can never block another. concurrency: - group: azure-login-live-tests + group: azure-login-live-tests-${{ github.ref }} cancel-in-progress: false env: # Created once in setup; the positive and embedded "can access" assertions - # target this group. - RG_POSITIVE: GitHubAction_CI_Group + # target this group. Suffixed with the run id so every run is isolated. + RG_POSITIVE: GitHubAction_CI_Group_${{ github.run_id }} LOCATION: eastus # Intentionally NEVER created: the negative permission/not-found assertions # target this name so they fail as expected. @@ -38,7 +41,7 @@ jobs: with: creds: ${{ secrets.PROVISION_CREDS }} - name: Create resource group - run: az group create --name "$RG_POSITIVE" --location "$LOCATION" --output none + run: az group create --name "${{ env.RG_POSITIVE }}" --location "${{ env.LOCATION }}" --output none # ================================================================ POSITIVE Positive_BasicTest: @@ -77,7 +80,7 @@ jobs: - name: Run Azure Cli run: | az account show --output none - az group show --name GitHubAction_CI_Group --output none + az group show --name "${{ env.RG_POSITIVE }}" --output none - name: Run Azure PowerShell uses: azure/powershell@v3 @@ -121,7 +124,7 @@ jobs: - name: Run Azure Cli run: | az account show --output none - az group show --name GitHubAction_CI_Group --output none + az group show --name "${{ env.RG_POSITIVE }}" --output none - name: Run Azure PowerShell uses: azure/powershell@v3 @@ -165,7 +168,7 @@ jobs: - name: Run Azure Cli run: | az account show --output none - az group show --name GitHubAction_CI_Group --output none + az group show --name "${{ env.RG_POSITIVE }}" --output none - name: Login with creds, wrong boolean value uses: ./ @@ -176,7 +179,7 @@ jobs: - name: Run Azure Cli run: | az account show --output none - az group show --name GitHubAction_CI_Group --output none + az group show --name "${{ env.RG_POSITIVE }}" --output none - name: Login with creds, allow no subscription uses: ./ @@ -188,7 +191,7 @@ jobs: - name: Run Azure Cli run: | az account show --output none - az group show --name GitHubAction_CI_Group --output none + az group show --name "${{ env.RG_POSITIVE }}" --output none - name: Run Azure PowerShell uses: azure/powershell@v3 @@ -521,7 +524,7 @@ jobs: - name: Run Azure Cli run: | az account show --output none - az group show --name GitHubAction_CI_Group --output none + az group show --name "${{ env.RG_POSITIVE }}" --output none - name: Run Azure PowerShell id: ps_8 @@ -531,7 +534,7 @@ jobs: azPSVersion: "latest" inlineScript: | (Get-AzContext).Environment.Name -eq 'AzureCloud' - (Get-AzResourceGroup -Name GitHubAction_CI_Group).ResourceGroupName -eq 'GitHubAction_CI_Group' + (Get-AzResourceGroup -Name $env:RG_POSITIVE).ResourceGroupName -eq $env:RG_POSITIVE - name: Check Last step failed if: steps.ps_8.outcome == 'success' @@ -549,7 +552,7 @@ jobs: - name: Run Azure Cli run: | az account show --output none - az group show --name GitHubAction_CI_Group --output none + az group show --name "${{ env.RG_POSITIVE }}" --output none - name: Run Azure PowerShell id: ps_9 @@ -559,7 +562,7 @@ jobs: azPSVersion: "latest" inlineScript: | (Get-AzContext).Environment.Name -eq 'AzureCloud' - (Get-AzResourceGroup -Name GitHubAction_CI_Group).ResourceGroupName -eq 'GitHubAction_CI_Group' + (Get-AzResourceGroup -Name $env:RG_POSITIVE).ResourceGroupName -eq $env:RG_POSITIVE - name: Check Last step failed if: steps.ps_9.outcome == 'success' @@ -687,4 +690,4 @@ jobs: with: creds: ${{ secrets.PROVISION_CREDS }} - name: Delete resource group - run: az group delete --name "$RG_POSITIVE" --yes --output none || true + run: az group delete --name "${{ env.RG_POSITIVE }}" --yes --output none || true diff --git a/src/common/Utils.ts b/src/common/Utils.ts index 8d36b3cd7..ecd45df94 100644 --- a/src/common/Utils.ts +++ b/src/common/Utils.ts @@ -7,8 +7,9 @@ import { AzPSConstants, AzPSUtils } from '../PowerShell/AzPSUtils'; export function setUserAgent(): void { let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex'); let actionName = 'AzureLogin'; - process.env.AZURE_HTTP_USER_AGENT = (!!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT} ` : '') + `GITHUBACTIONS/${actionName}@v3_${usrAgentRepo}_${process.env.RUNNER_ENVIRONMENT}_${process.env.GITHUB_RUN_ID}`; - process.env.AZUREPS_HOST_ENVIRONMENT = (!!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT} ` : '') + `GITHUBACTIONS/${actionName}@v3_${usrAgentRepo}_${process.env.RUNNER_ENVIRONMENT}_${process.env.GITHUB_RUN_ID}`; + let actionRef = process.env.GITHUB_ACTION_REF || 'unknown'; + process.env.AZURE_HTTP_USER_AGENT = (!!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT} ` : '') + `GITHUBACTIONS/${actionName}@${actionRef}_${usrAgentRepo}_${process.env.RUNNER_ENVIRONMENT}_${process.env.GITHUB_RUN_ID}`; + process.env.AZUREPS_HOST_ENVIRONMENT = (!!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT} ` : '') + `GITHUBACTIONS/${actionName}@${actionRef}_${usrAgentRepo}_${process.env.RUNNER_ENVIRONMENT}_${process.env.GITHUB_RUN_ID}`; } export async function cleanupAzCLIAccounts(): Promise {