Compare commits

..

5 Commits

Author SHA1 Message Date
MoChilia
e15b166166 prepare release v1.6.0 2024-01-09 11:08:09 +08:00
Shiying Chen
3f2bf91b4d Fix #384: Remove az account clear in az cli (#398) 2024-01-08 18:26:20 +08:00
Shiying Chen
b5038826b1 Add pre: and post: action for cleaning up (#384)
* pre and post cleanup-cli

* exec azpath

* enable azure powershell part

* set user agent

* extract utils

* divide cleanup

* extract azpsconfig class

* fix test

* move runpsscript

* change to AzPSUtils

* fix typo
2023-12-28 17:00:03 +08:00
Yan Xu
45c3280904 update workflow files for macos (#390) 2023-12-27 14:30:51 +08:00
Josh Soref
165d6877fd Update Workflows (#385)
* Consistently use azure/powershell@v1

* Consistently use actions/checkout@v4

* Consistently use actions/setup-node@v4

* Consistently use actions/github-script@v7

* Consistently use actions/stale@v8

* Specify codql language as javascript

See https://api.github.com/repos/github/codeql-action/issues/comments/762138640

* Name ci.yml

* CodeQL does not need a special code
2023-12-27 10:26:03 +08:00
28 changed files with 873 additions and 763 deletions

View File

@@ -30,7 +30,7 @@ jobs:
az --version
- name: Check out repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: 'Az CLI login with subscription'
uses: azure/login@v1

View File

@@ -9,86 +9,6 @@ permissions:
jobs:
OSTest:
runs-on: macos-latest
environment: Automation test
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v3.5.2
- name: Set Node.js 16.x for GitHub Action
uses: actions/setup-node@v1
with:
node-version: 16.x
- name: 'Validate build'
run: |
npm install
npm run build
npm run test
- name: Login with creds
continue-on-error: true
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
id: ps_1
continue-on-error: true
uses: azure/powershell@v1.2.0
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_1.outcome == 'success'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
- name: Login with individual parameters
id: login_2
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 again
run: |
az account show --output none
- name: Run Azure PowerShell again
id: ps_2
continue-on-error: true
uses: azure/powershell@v1.2.0
with:
azPSVersion: "latest"
inlineScript: |
(Get-AzContext).Environment.Name -eq 'AzureCloud'
- name: Check Last step failed
if: steps.ps_2.outcome == 'success'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
PermissionTest:
strategy:
matrix:
@@ -99,10 +19,10 @@ jobs:
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v3.5.2
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 16.x
@@ -130,7 +50,7 @@ jobs:
- name: Check Last step failed
if: steps.cli_3.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -138,7 +58,7 @@ jobs:
- name: Run Azure PowerShell
id: ps_3
continue-on-error: true
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -148,7 +68,7 @@ jobs:
- name: Check Last step failed
if: steps.ps_3.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -162,10 +82,10 @@ jobs:
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v3.5.2
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 16.x
@@ -184,7 +104,7 @@ jobs:
- name: Check Last step failed
if: steps.login_4.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -199,7 +119,7 @@ jobs:
- name: Check Last step failed
if: steps.login_5.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -213,7 +133,7 @@ jobs:
- name: Check Last step failed
if: steps.login_6.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -229,7 +149,7 @@ jobs:
- name: Check Last step failed
if: steps.login_7.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -246,7 +166,7 @@ jobs:
- name: Check Last step failed
if: steps.login_8.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -266,7 +186,7 @@ jobs:
- name: Run Azure PowerShell
id: ps_8
continue-on-error: true
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -276,7 +196,7 @@ jobs:
- name: Check Last step failed
if: steps.ps_8.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -296,7 +216,7 @@ jobs:
- name: Run Azure PowerShell
id: ps_9
continue-on-error: true
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -306,7 +226,7 @@ jobs:
- name: Check Last step failed
if: steps.ps_9.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -325,7 +245,7 @@ jobs:
- name: Check Last step failed
if: steps.login_10.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -342,7 +262,7 @@ jobs:
- name: Check Last step failed
if: steps.login_11.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -362,7 +282,7 @@ jobs:
- name: Check Last step failed
if: steps.login_12.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -378,7 +298,7 @@ jobs:
- name: Check Last step failed
if: steps.login_13.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -394,7 +314,7 @@ jobs:
- name: Check Last step failed
if: steps.login_14.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -409,7 +329,7 @@ jobs:
- name: Check Last step failed
if: steps.login_15.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')
@@ -423,10 +343,10 @@ jobs:
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v3.5.2
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 16.x
@@ -442,7 +362,7 @@ jobs:
- name: Check Last step failed
if: steps.login_14.outcome == 'success'
uses: actions/github-script@v3
uses: actions/github-script@v7
with:
script: |
core.setFailed('Last action should fail but not. Please check it.')

View File

@@ -12,16 +12,16 @@ jobs:
BasicTest:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, self_linux, self_windows]
os: [ubuntu-latest, windows-latest, macos-latest, self_linux, self_windows]
runs-on: ${{ matrix.os }}
environment: Automation test
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v3.5.2
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 16.x
@@ -47,7 +47,7 @@ jobs:
az vm list --output none
- name: Run Azure PowerShell
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -71,7 +71,7 @@ jobs:
az account show --output none
- name: Run Azure PowerShell again
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -94,7 +94,7 @@ jobs:
az vm list --output none
- name: Run Azure PowerShell
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -108,16 +108,16 @@ jobs:
ParameterTest:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
environment: Automation test
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v3.5.2
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 16.x
@@ -164,7 +164,7 @@ jobs:
az vm list --output none
- name: Run Azure PowerShell
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -189,7 +189,7 @@ jobs:
az account show --output none
- name: Run Azure PowerShell again
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -207,17 +207,21 @@ jobs:
enable-AzPSSession: true
- name: Run Azure Cli
shell: pwsh
run: |
az account show --output none
$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@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
$checkResult = (Get-AzContext -ListAvailable).Count -eq 2
if(-not $checkResult){
throw "Not all checks passed!"
throw "Not all checks passed!"
}
- name: Login with creds, no subscription, allow no subscription
@@ -232,7 +236,7 @@ jobs:
az account show --output none
- name: Run Azure PowerShell
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -250,10 +254,10 @@ jobs:
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v3.5.2
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 16.x
@@ -274,7 +278,7 @@ jobs:
az account show --output none
- name: Run Azure PowerShell
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -297,7 +301,7 @@ jobs:
az vm list --output none
- name: Run Azure PowerShell
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -321,7 +325,7 @@ jobs:
az account show --output none
- name: Run Azure PowerShell
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -345,7 +349,7 @@ jobs:
az vm list --output none
- name: Run Azure PowerShell
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |

View File

@@ -11,14 +11,14 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout from PR branch
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
# Using 16.x version as an example
- name: Set Node.js 16.x for GitHub Action
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 16.x

View File

@@ -1,3 +1,5 @@
name: Build and Test
on:
pull_request:
branches:
@@ -16,10 +18,10 @@ jobs:
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Set Node.js 16.x for GitHub Action
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 16.x

View File

@@ -14,23 +14,13 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
with:
languages: javascript
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)

View File

@@ -14,7 +14,7 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/stale@v3
- uses: actions/stale@v8
name: Setting issue as idle
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
@@ -25,7 +25,7 @@ jobs:
operations-per-run: 100
exempt-issue-labels: 'backlog'
- uses: actions/stale@v3
- uses: actions/stale@v8
name: Setting PR as idle
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -7,9 +7,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 16.x
- name: Run Markdownlint

View File

@@ -235,7 +235,7 @@ jobs:
az account show
- name: Azure PowerShell script
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -323,7 +323,7 @@ jobs:
az account show
- name: Azure PowerShell script
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -394,7 +394,7 @@ jobs:
az account show
- name: Azure PowerShell script
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -461,7 +461,7 @@ jobs:
az account show
- name: Azure PowerShell script
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -549,7 +549,7 @@ jobs:
az account show
- name: Run Azure PowerShell
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
@@ -570,7 +570,7 @@ This action doesn't implement ```az logout``` by default at the end of execution
az account clear
- name: Azure PowerShell script
uses: azure/powershell@v1.2.0
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |

View File

@@ -2,7 +2,7 @@ import * as os from 'os';
import { AzPSLogin } from '../../src/PowerShell/AzPSLogin';
import { LoginConfig } from '../../src/common/LoginConfig';
import AzPSConstants from '../../src/PowerShell/AzPSConstants';
import { AzPSConstants, AzPSUtils } from '../../src/PowerShell/AzPSUtils';
let azpsLogin: AzPSLogin;
jest.setTimeout(30000);
@@ -36,7 +36,7 @@ describe('Testing login', () => {
describe('Testing set module path', () => {
test('setDefaultPSModulePath should work', () => {
azpsLogin.setPSModulePathForGitHubRunner();
AzPSUtils.setPSModulePathForGitHubRunner();
const runner: string = process.env.RUNNER_OS || os.type();
if(runner.toLowerCase() === "linux"){
expect(process.env.PSModulePath).toContain(AzPSConstants.DEFAULT_AZ_PATH_ON_LINUX);
@@ -63,7 +63,7 @@ describe('Testing runPSScript', () => {
}
return ConvertTo-Json $output`;
let psVersion: string = await AzPSLogin.runPSScript(script);
let psVersion: string = await AzPSUtils.runPSScript(script);
expect(psVersion === null).toBeFalsy();
});
@@ -82,7 +82,7 @@ describe('Testing runPSScript', () => {
return ConvertTo-Json $output`;
try{
await AzPSLogin.runPSScript(script);
await AzPSUtils.runPSScript(script);
throw new Error("The last step should fail.");
}catch(error){
expect(error.message.includes("Azure PowerShell login failed with error: You cannot call a method on a null-valued expression.")).toBeTruthy();

View File

@@ -40,7 +40,7 @@ describe("Getting AzLogin PS script", () => {
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; $psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
expect(loginMethod).toBe('service principal with secret');
});
});
@@ -61,7 +61,7 @@ describe("Getting AzLogin PS script", () => {
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; $psLoginSecrets = ConvertTo-SecureString 'client-se''cret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-se''cret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
expect(loginMethod).toBe('service principal with secret');
});
});
@@ -82,7 +82,7 @@ describe("Getting AzLogin PS script", () => {
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; $psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
expect(loginScript.includes("$psLoginSecrets = ConvertTo-SecureString 'client-secret' -AsPlainText -Force; $psLoginCredential = New-Object System.Management.Automation.PSCredential('client-id', $psLoginSecrets); Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -Credential $psLoginCredential | out-null;")).toBeTruthy();
expect(loginMethod).toBe('service principal with secret');
});
});
@@ -100,7 +100,7 @@ describe("Getting AzLogin PS script", () => {
loginConfig.initialize();
jest.spyOn(loginConfig, 'getFederatedToken').mockImplementation(async () => {loginConfig.federatedToken = "fake-token";});
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -ApplicationId 'client-id' -FederatedToken 'fake-token' | out-null;")).toBeTruthy();
expect(loginScript.includes("Connect-AzAccount -ServicePrincipal -Environment 'azurecloud' -Tenant 'tenant-id' -Subscription 'subscription-id' -ApplicationId 'client-id' -FederatedToken 'fake-token' | out-null;")).toBeTruthy();
expect(loginMethod).toBe('OIDC');
});
});
@@ -115,7 +115,7 @@ describe("Getting AzLogin PS script", () => {
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; Connect-AzAccount -Identity -Environment 'azurecloud' -Subscription 'subscription-id' | out-null;")).toBeTruthy();
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -Subscription 'subscription-id' | out-null;")).toBeTruthy();
expect(loginMethod).toBe('system-assigned managed identity');
});
});
@@ -130,7 +130,7 @@ describe("Getting AzLogin PS script", () => {
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; Connect-AzAccount -Identity -Environment 'azurecloud' | out-null;")).toBeTruthy();
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' | out-null;")).toBeTruthy();
expect(loginMethod).toBe('system-assigned managed identity');
});
});
@@ -145,7 +145,7 @@ describe("Getting AzLogin PS script", () => {
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
expect(loginScript.includes("Clear-AzContext -Scope Process; Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; Connect-AzAccount -Identity -Environment 'azurecloud' -AccountId 'client-id' | out-null;")).toBeTruthy();
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -AccountId 'client-id' | out-null;")).toBeTruthy();
expect(loginMethod).toBe('user-assigned managed identity');
});
});

View File

@@ -39,4 +39,6 @@ branding:
color: 'blue'
runs:
using: 'node16'
pre: 'lib/cleanup.js'
main: 'lib/main.js'
post: 'lib/cleanup.js'

View File

@@ -46,9 +46,6 @@ class AzureCliLogin {
return __awaiter(this, void 0, void 0, function* () {
core.info(`Running Azure CLI Login.`);
this.azPath = yield io.which("az", true);
if (!this.azPath) {
throw new Error("Azure CLI is not found in the runner.");
}
core.debug(`Azure CLI path: ${this.azPath}`);
let output = "";
const execOptions = {
@@ -60,7 +57,6 @@ class AzureCliLogin {
};
yield this.executeAzCliCommand(["--version"], true, execOptions);
core.debug(`Azure CLI version used:\n${output}`);
yield this.executeAzCliCommand(["account", "clear"], true, execOptions);
this.setAzurestackEnvIfNecessary();
yield this.executeAzCliCommand(["cloud", "set", "-n", this.loginConfig.environment], false);
core.info(`Done setting cloud: "${this.loginConfig.environment}"`);

View File

@@ -1,9 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class AzPSConstants {
}
exports.default = AzPSConstants;
AzPSConstants.DEFAULT_AZ_PATH_ON_LINUX = '/usr/share';
AzPSConstants.DEFAULT_AZ_PATH_ON_WINDOWS = 'C:\\Modules';
AzPSConstants.AzAccounts = "Az.Accounts";
AzPSConstants.PowerShell_CmdName = "pwsh";

View File

@@ -37,12 +37,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
exports.AzPSLogin = void 0;
const core = __importStar(require("@actions/core"));
const exec = __importStar(require("@actions/exec"));
const io = __importStar(require("@actions/io"));
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const AzPSScriptBuilder_1 = __importDefault(require("./AzPSScriptBuilder"));
const AzPSConstants_1 = __importDefault(require("./AzPSConstants"));
const AzPSUtils_1 = require("./AzPSUtils");
class AzPSLogin {
constructor(loginConfig) {
this.loginConfig = loginConfig;
@@ -50,77 +46,14 @@ class AzPSLogin {
login() {
return __awaiter(this, void 0, void 0, function* () {
core.info(`Running Azure PowerShell Login.`);
this.setPSModulePathForGitHubRunner();
yield this.importLatestAzAccounts();
AzPSUtils_1.AzPSUtils.setPSModulePathForGitHubRunner();
yield AzPSUtils_1.AzPSUtils.importLatestAzAccounts();
const [loginMethod, loginScript] = yield AzPSScriptBuilder_1.default.getAzPSLoginScript(this.loginConfig);
core.info(`Attempting Azure PowerShell login by using ${loginMethod}...`);
core.debug(`Azure PowerShell Login Script: ${loginScript}`);
yield AzPSLogin.runPSScript(loginScript);
yield AzPSUtils_1.AzPSUtils.runPSScript(loginScript);
console.log(`Running Azure PowerShell Login successfully.`);
});
}
setPSModulePathForGitHubRunner() {
const runner = process.env.RUNNER_OS || os.type();
switch (runner.toLowerCase()) {
case "linux":
this.pushPSModulePath(AzPSConstants_1.default.DEFAULT_AZ_PATH_ON_LINUX);
break;
case "windows":
case "windows_nt":
this.pushPSModulePath(AzPSConstants_1.default.DEFAULT_AZ_PATH_ON_WINDOWS);
break;
case "macos":
case "darwin":
core.warning(`Skip setting the default PowerShell module path for OS ${runner.toLowerCase()}.`);
break;
default:
core.warning(`Skip setting the default PowerShell module path for unknown OS ${runner.toLowerCase()}.`);
break;
}
}
pushPSModulePath(psModulePath) {
process.env.PSModulePath = `${psModulePath}${path.delimiter}${process.env.PSModulePath}`;
core.debug(`Set PSModulePath as ${process.env.PSModulePath}`);
}
importLatestAzAccounts() {
return __awaiter(this, void 0, void 0, function* () {
let importLatestAccountsScript = AzPSScriptBuilder_1.default.getImportLatestModuleScript(AzPSConstants_1.default.AzAccounts);
core.debug(`The script to import the latest Az.Accounts: ${importLatestAccountsScript}`);
let azAccountsPath = yield AzPSLogin.runPSScript(importLatestAccountsScript);
core.debug(`The latest Az.Accounts used: ${azAccountsPath}`);
});
}
static runPSScript(psScript) {
return __awaiter(this, void 0, void 0, function* () {
let outputString = "";
let commandStdErr = false;
const options = {
silent: true,
listeners: {
stdout: (data) => {
outputString += data.toString();
},
stderr: (data) => {
let error = data.toString();
if (error && error.trim().length !== 0) {
commandStdErr = true;
core.error(error);
}
}
}
};
let psPath = yield io.which(AzPSConstants_1.default.PowerShell_CmdName, true);
yield exec.exec(`"${psPath}"`, ["-Command", psScript], options);
if (commandStdErr) {
throw new Error('Azure PowerShell login failed with errors.');
}
const result = JSON.parse(outputString.trim());
console.log(result);
if (!(result.Success)) {
throw new Error(`Azure PowerShell login failed with error: ${result.Error}`);
}
return result.Result;
});
}
}
exports.AzPSLogin = AzPSLogin;

View File

@@ -31,8 +31,7 @@ class AzPSScriptBuilder {
static getAzPSLoginScript(loginConfig) {
return __awaiter(this, void 0, void 0, function* () {
let loginMethodName = "";
let commands = 'Clear-AzContext -Scope Process; ';
commands += 'Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; ';
let commands = "";
if (loginConfig.environment.toLowerCase() == "azurestack") {
commands += `Add-AzEnvironment -Name '${loginConfig.environment}' -ARMEndpoint '${loginConfig.resourceManagerEndpointUrl}' | out-null;`;
}

119
lib/PowerShell/AzPSUtils.js Normal file
View File

@@ -0,0 +1,119 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AzPSUtils = exports.AzPSConstants = void 0;
const core = __importStar(require("@actions/core"));
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const exec = __importStar(require("@actions/exec"));
const io = __importStar(require("@actions/io"));
const AzPSScriptBuilder_1 = __importDefault(require("./AzPSScriptBuilder"));
class AzPSConstants {
}
exports.AzPSConstants = AzPSConstants;
AzPSConstants.DEFAULT_AZ_PATH_ON_LINUX = '/usr/share';
AzPSConstants.DEFAULT_AZ_PATH_ON_WINDOWS = 'C:\\Modules';
AzPSConstants.AzAccounts = "Az.Accounts";
AzPSConstants.PowerShell_CmdName = "pwsh";
class AzPSUtils {
static setPSModulePathForGitHubRunner() {
return __awaiter(this, void 0, void 0, function* () {
const runner = process.env.RUNNER_OS || os.type();
switch (runner.toLowerCase()) {
case "linux":
AzPSUtils.pushPSModulePath(AzPSConstants.DEFAULT_AZ_PATH_ON_LINUX);
break;
case "windows":
case "windows_nt":
AzPSUtils.pushPSModulePath(AzPSConstants.DEFAULT_AZ_PATH_ON_WINDOWS);
break;
case "macos":
case "darwin":
core.warning(`Skip setting the default PowerShell module path for OS ${runner.toLowerCase()}.`);
break;
default:
core.warning(`Skip setting the default PowerShell module path for unknown OS ${runner.toLowerCase()}.`);
break;
}
});
}
static pushPSModulePath(psModulePath) {
process.env.PSModulePath = `${psModulePath}${path.delimiter}${process.env.PSModulePath}`;
core.debug(`Set PSModulePath as ${process.env.PSModulePath}`);
}
static importLatestAzAccounts() {
return __awaiter(this, void 0, void 0, function* () {
let importLatestAccountsScript = AzPSScriptBuilder_1.default.getImportLatestModuleScript(AzPSConstants.AzAccounts);
core.debug(`The script to import the latest Az.Accounts: ${importLatestAccountsScript}`);
let azAccountsPath = yield AzPSUtils.runPSScript(importLatestAccountsScript);
core.debug(`The latest Az.Accounts used: ${azAccountsPath}`);
});
}
static runPSScript(psScript) {
return __awaiter(this, void 0, void 0, function* () {
let outputString = "";
let commandStdErr = false;
const options = {
silent: true,
listeners: {
stdout: (data) => {
outputString += data.toString();
},
stderr: (data) => {
let error = data.toString();
if (error && error.trim().length !== 0) {
commandStdErr = true;
core.error(error);
}
}
}
};
let psPath = yield io.which(AzPSConstants.PowerShell_CmdName, true);
yield exec.exec(`"${psPath}"`, ["-Command", psScript], options);
if (commandStdErr) {
throw new Error('Azure PowerShell login failed with errors.');
}
const result = JSON.parse(outputString.trim());
console.log(result);
if (!(result.Success)) {
throw new Error(`Azure PowerShell login failed with error: ${result.Error}`);
}
return result.Result;
});
}
}
exports.AzPSUtils = AzPSUtils;

52
lib/cleanup.js Normal file
View File

@@ -0,0 +1,52 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const Utils_1 = require("./common/Utils");
function cleanup() {
return __awaiter(this, void 0, void 0, function* () {
try {
(0, Utils_1.setUserAgent)();
yield (0, Utils_1.cleanupAzCLIAccounts)();
if (core.getInput('enable-AzPSSession').toLowerCase() === "true") {
yield (0, Utils_1.cleanupAzPSAccounts)();
}
}
catch (error) {
core.setFailed(`Login cleanup failed with ${error}. Make sure 'az' is installed on the runner. If 'enable-AzPSSession' is true, make sure 'pwsh' is installed on the runner together with Azure PowerShell module.`);
core.debug(error.stack);
}
});
}
cleanup();

75
lib/common/Utils.js Normal file
View File

@@ -0,0 +1,75 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.cleanupAzPSAccounts = exports.cleanupAzCLIAccounts = exports.setUserAgent = void 0;
const core = __importStar(require("@actions/core"));
const exec = __importStar(require("@actions/exec"));
const io = __importStar(require("@actions/io"));
const crypto = __importStar(require("crypto"));
const AzPSUtils_1 = require("../PowerShell/AzPSUtils");
function setUserAgent() {
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}@v1_${usrAgentRepo}`;
process.env.AZUREPS_HOST_ENVIRONMENT = (!!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT} ` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
}
exports.setUserAgent = setUserAgent;
function cleanupAzCLIAccounts() {
return __awaiter(this, void 0, void 0, function* () {
let azPath = yield io.which("az", true);
if (!azPath) {
throw new Error("Azure CLI is not found in the runner.");
}
core.debug(`Azure CLI path: ${azPath}`);
core.info("Clearing azure cli accounts from the local cache.");
yield exec.exec(`"${azPath}"`, ["account", "clear"]);
});
}
exports.cleanupAzCLIAccounts = cleanupAzCLIAccounts;
function cleanupAzPSAccounts() {
return __awaiter(this, void 0, void 0, function* () {
let psPath = yield io.which(AzPSUtils_1.AzPSConstants.PowerShell_CmdName, true);
if (!psPath) {
throw new Error("PowerShell is not found in the runner.");
}
core.debug(`PowerShell path: ${psPath}`);
core.debug("Importing Azure PowerShell module.");
AzPSUtils_1.AzPSUtils.setPSModulePathForGitHubRunner();
yield AzPSUtils_1.AzPSUtils.importLatestAzAccounts();
core.info("Clearing azure powershell accounts from the local cache.");
yield exec.exec(`"${psPath}"`, ["-Command", "Clear-AzContext", "-Scope", "Process"]);
yield exec.exec(`"${psPath}"`, ["-Command", "Clear-AzContext", "-Scope", "CurrentUser", "-Force", "-ErrorAction", "SilentlyContinue"]);
});
}
exports.cleanupAzPSAccounts = cleanupAzPSAccounts;

View File

@@ -33,20 +33,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const Utils_1 = require("./common/Utils");
const AzPSLogin_1 = require("./PowerShell/AzPSLogin");
const LoginConfig_1 = require("./common/LoginConfig");
const AzureCliLogin_1 = require("./Cli/AzureCliLogin");
var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : "";
var azPSHostEnv = !!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT}` : "";
function main() {
return __awaiter(this, void 0, void 0, function* () {
try {
let usrAgentRepo = `${process.env.GITHUB_REPOSITORY}`;
let actionName = 'AzureLogin';
let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
let azurePSHostEnv = (!!azPSHostEnv ? `${azPSHostEnv}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
(0, Utils_1.setUserAgent)();
// prepare the login configuration
var loginConfig = new LoginConfig_1.LoginConfig();
yield loginConfig.initialize();
@@ -61,14 +55,9 @@ function main() {
}
}
catch (error) {
core.setFailed(`Login failed with ${error}. Make sure 'az' is installed on the runner. If 'enable-AzPSSession' is true, make sure 'pwsh' is installed on the runner together with Azure PowerShell module. Double check if the 'auth-type' is correct. Refer to https://github.com/Azure/login#readme for more information.`);
core.setFailed(`Login failed with ${error}. Double check if the 'auth-type' is correct. Refer to https://github.com/Azure/login#readme for more information.`);
core.debug(error.stack);
}
finally {
// Reset AZURE_HTTP_USER_AGENT
core.exportVariable('AZURE_HTTP_USER_AGENT', prefix);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv);
}
});
}
main();

View File

@@ -17,9 +17,6 @@ export class AzureCliLogin {
async login() {
core.info(`Running Azure CLI Login.`);
this.azPath = await io.which("az", true);
if (!this.azPath) {
throw new Error("Azure CLI is not found in the runner.");
}
core.debug(`Azure CLI path: ${this.azPath}`);
let output: string = "";
@@ -34,8 +31,6 @@ export class AzureCliLogin {
await this.executeAzCliCommand(["--version"], true, execOptions);
core.debug(`Azure CLI version used:\n${output}`);
await this.executeAzCliCommand(["account", "clear"], true, execOptions);
this.setAzurestackEnvIfNecessary();
await this.executeAzCliCommand(["cloud", "set", "-n", this.loginConfig.environment], false);

View File

@@ -1,7 +0,0 @@
export default class AzPSConstants {
static readonly DEFAULT_AZ_PATH_ON_LINUX: string = '/usr/share';
static readonly DEFAULT_AZ_PATH_ON_WINDOWS: string = 'C:\\Modules';
static readonly AzAccounts: string = "Az.Accounts";
static readonly PowerShell_CmdName = "pwsh";
}

View File

@@ -1,19 +1,9 @@
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as io from '@actions/io';
import * as os from 'os';
import * as path from 'path';
import AzPSScriptBuilder from './AzPSScriptBuilder';
import AzPSConstants from './AzPSConstants';
import { AzPSUtils } from './AzPSUtils';
import { LoginConfig } from '../common/LoginConfig';
interface PSResultType {
Result: string;
Success: boolean;
Error: string;
}
export class AzPSLogin {
loginConfig: LoginConfig;
@@ -23,78 +13,12 @@ export class AzPSLogin {
async login() {
core.info(`Running Azure PowerShell Login.`);
this.setPSModulePathForGitHubRunner();
await this.importLatestAzAccounts();
AzPSUtils.setPSModulePathForGitHubRunner();
await AzPSUtils.importLatestAzAccounts();
const [loginMethod, loginScript] = await AzPSScriptBuilder.getAzPSLoginScript(this.loginConfig);
core.info(`Attempting Azure PowerShell login by using ${loginMethod}...`);
core.debug(`Azure PowerShell Login Script: ${loginScript}`);
await AzPSLogin.runPSScript(loginScript);
await AzPSUtils.runPSScript(loginScript);
console.log(`Running Azure PowerShell Login successfully.`);
}
setPSModulePathForGitHubRunner() {
const runner: string = process.env.RUNNER_OS || os.type();
switch (runner.toLowerCase()) {
case "linux":
this.pushPSModulePath(AzPSConstants.DEFAULT_AZ_PATH_ON_LINUX);
break;
case "windows":
case "windows_nt":
this.pushPSModulePath(AzPSConstants.DEFAULT_AZ_PATH_ON_WINDOWS);
break;
case "macos":
case "darwin":
core.warning(`Skip setting the default PowerShell module path for OS ${runner.toLowerCase()}.`);
break;
default:
core.warning(`Skip setting the default PowerShell module path for unknown OS ${runner.toLowerCase()}.`);
break;
}
}
private pushPSModulePath(psModulePath: string) {
process.env.PSModulePath = `${psModulePath}${path.delimiter}${process.env.PSModulePath}`;
core.debug(`Set PSModulePath as ${process.env.PSModulePath}`);
}
private async importLatestAzAccounts() {
let importLatestAccountsScript: string = AzPSScriptBuilder.getImportLatestModuleScript(AzPSConstants.AzAccounts);
core.debug(`The script to import the latest Az.Accounts: ${importLatestAccountsScript}`);
let azAccountsPath: string = await AzPSLogin.runPSScript(importLatestAccountsScript);
core.debug(`The latest Az.Accounts used: ${azAccountsPath}`);
}
static async runPSScript(psScript: string): Promise<string> {
let outputString: string = "";
let commandStdErr = false;
const options: any = {
silent: true,
listeners: {
stdout: (data: Buffer) => {
outputString += data.toString();
},
stderr: (data: Buffer) => {
let error = data.toString();
if (error && error.trim().length !== 0) {
commandStdErr = true;
core.error(error);
}
}
}
};
let psPath: string = await io.which(AzPSConstants.PowerShell_CmdName, true);
await exec.exec(`"${psPath}"`, ["-Command", psScript], options)
if (commandStdErr) {
throw new Error('Azure PowerShell login failed with errors.');
}
const result: PSResultType = JSON.parse(outputString.trim());
console.log(result);
if (!(result.Success)) {
throw new Error(`Azure PowerShell login failed with error: ${result.Error}`);
}
return result.Result;
}
}

View File

@@ -1,4 +1,3 @@
import AzPSConstants from "./AzPSConstants";
import { LoginConfig } from '../common/LoginConfig';
export default class AzPSScriptBuilder {
@@ -24,8 +23,7 @@ export default class AzPSScriptBuilder {
static async getAzPSLoginScript(loginConfig: LoginConfig) {
let loginMethodName = "";
let commands = 'Clear-AzContext -Scope Process; ';
commands += 'Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue; ';
let commands = "";
if (loginConfig.environment.toLowerCase() == "azurestack") {
commands += `Add-AzEnvironment -Name '${loginConfig.environment}' -ARMEndpoint '${loginConfig.resourceManagerEndpointUrl}' | out-null;`;

View File

@@ -0,0 +1,85 @@
import * as core from '@actions/core';
import * as os from 'os';
import * as path from 'path';
import * as exec from '@actions/exec';
import * as io from '@actions/io';
import AzPSScriptBuilder from './AzPSScriptBuilder';
interface PSResultType {
Result: string;
Success: boolean;
Error: string;
}
export class AzPSConstants {
static readonly DEFAULT_AZ_PATH_ON_LINUX: string = '/usr/share';
static readonly DEFAULT_AZ_PATH_ON_WINDOWS: string = 'C:\\Modules';
static readonly AzAccounts: string = "Az.Accounts";
static readonly PowerShell_CmdName = "pwsh";
}
export class AzPSUtils {
static async setPSModulePathForGitHubRunner() {
const runner: string = process.env.RUNNER_OS || os.type();
switch (runner.toLowerCase()) {
case "linux":
AzPSUtils.pushPSModulePath(AzPSConstants.DEFAULT_AZ_PATH_ON_LINUX);
break;
case "windows":
case "windows_nt":
AzPSUtils.pushPSModulePath(AzPSConstants.DEFAULT_AZ_PATH_ON_WINDOWS);
break;
case "macos":
case "darwin":
core.warning(`Skip setting the default PowerShell module path for OS ${runner.toLowerCase()}.`);
break;
default:
core.warning(`Skip setting the default PowerShell module path for unknown OS ${runner.toLowerCase()}.`);
break;
}
}
private static pushPSModulePath(psModulePath: string) {
process.env.PSModulePath = `${psModulePath}${path.delimiter}${process.env.PSModulePath}`;
core.debug(`Set PSModulePath as ${process.env.PSModulePath}`);
}
static async importLatestAzAccounts() {
let importLatestAccountsScript: string = AzPSScriptBuilder.getImportLatestModuleScript(AzPSConstants.AzAccounts);
core.debug(`The script to import the latest Az.Accounts: ${importLatestAccountsScript}`);
let azAccountsPath: string = await AzPSUtils.runPSScript(importLatestAccountsScript);
core.debug(`The latest Az.Accounts used: ${azAccountsPath}`);
}
static async runPSScript(psScript: string): Promise<string> {
let outputString: string = "";
let commandStdErr = false;
const options: any = {
silent: true,
listeners: {
stdout: (data: Buffer) => {
outputString += data.toString();
},
stderr: (data: Buffer) => {
let error = data.toString();
if (error && error.trim().length !== 0) {
commandStdErr = true;
core.error(error);
}
}
}
};
let psPath: string = await io.which(AzPSConstants.PowerShell_CmdName, true);
await exec.exec(`"${psPath}"`, ["-Command", psScript], options)
if (commandStdErr) {
throw new Error('Azure PowerShell login failed with errors.');
}
const result: PSResultType = JSON.parse(outputString.trim());
console.log(result);
if (!(result.Success)) {
throw new Error(`Azure PowerShell login failed with error: ${result.Error}`);
}
return result.Result;
}
}

19
src/cleanup.ts Normal file
View File

@@ -0,0 +1,19 @@
import * as core from '@actions/core';
import { setUserAgent, cleanupAzCLIAccounts, cleanupAzPSAccounts } from './common/Utils';
async function cleanup() {
try {
setUserAgent();
await cleanupAzCLIAccounts();
if(core.getInput('enable-AzPSSession').toLowerCase() === "true"){
await cleanupAzPSAccounts();
}
}
catch (error) {
core.setFailed(`Login cleanup failed with ${error}. Make sure 'az' is installed on the runner. If 'enable-AzPSSession' is true, make sure 'pwsh' is installed on the runner together with Azure PowerShell module.`);
core.debug(error.stack);
}
}
cleanup();

36
src/common/Utils.ts Normal file
View File

@@ -0,0 +1,36 @@
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as io from '@actions/io';
import * as crypto from 'crypto';
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}@v1_${usrAgentRepo}`;
process.env.AZUREPS_HOST_ENVIRONMENT = (!!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT} ` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
}
export async function cleanupAzCLIAccounts(): Promise<void> {
let azPath = await io.which("az", true);
if (!azPath) {
throw new Error("Azure CLI is not found in the runner.");
}
core.debug(`Azure CLI path: ${azPath}`);
core.info("Clearing azure cli accounts from the local cache.");
await exec.exec(`"${azPath}"`, ["account", "clear"]);
}
export async function cleanupAzPSAccounts(): Promise<void> {
let psPath: string = await io.which(AzPSConstants.PowerShell_CmdName, true);
if (!psPath) {
throw new Error("PowerShell is not found in the runner.");
}
core.debug(`PowerShell path: ${psPath}`);
core.debug("Importing Azure PowerShell module.");
AzPSUtils.setPSModulePathForGitHubRunner();
await AzPSUtils.importLatestAzAccounts();
core.info("Clearing azure powershell accounts from the local cache.");
await exec.exec(`"${psPath}"`, ["-Command", "Clear-AzContext", "-Scope", "Process"]);
await exec.exec(`"${psPath}"`, ["-Command", "Clear-AzContext", "-Scope", "CurrentUser", "-Force", "-ErrorAction", "SilentlyContinue"]);
}

View File

@@ -1,19 +1,12 @@
import * as core from '@actions/core';
import { setUserAgent } from './common/Utils';
import { AzPSLogin } from './PowerShell/AzPSLogin';
import { LoginConfig } from './common/LoginConfig';
import { AzureCliLogin } from './Cli/AzureCliLogin';
var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : "";
var azPSHostEnv = !!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT}` : "";
async function main() {
try {
let usrAgentRepo = `${process.env.GITHUB_REPOSITORY}`;
let actionName = 'AzureLogin';
let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
let azurePSHostEnv = (!!azPSHostEnv ? `${azPSHostEnv}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
setUserAgent();
// prepare the login configuration
var loginConfig = new LoginConfig();
@@ -31,14 +24,9 @@ async function main() {
}
}
catch (error) {
core.setFailed(`Login failed with ${error}. Make sure 'az' is installed on the runner. If 'enable-AzPSSession' is true, make sure 'pwsh' is installed on the runner together with Azure PowerShell module. Double check if the 'auth-type' is correct. Refer to https://github.com/Azure/login#readme for more information.`);
core.setFailed(`Login failed with ${error}. Double check if the 'auth-type' is correct. Refer to https://github.com/Azure/login#readme for more information.`);
core.debug(error.stack);
}
finally {
// Reset AZURE_HTTP_USER_AGENT
core.exportVariable('AZURE_HTTP_USER_AGENT', prefix);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv);
}
}
main();