Compare commits

..

12 Commits

Author SHA1 Message Date
Zainuden Veetikadam
4610f2b768 changes to environment input 2020-12-08 14:56:31 +05:30
Zainuden Veetikadam
ab062435f9 changes from arary to set 2020-12-08 14:49:48 +05:30
Zainuden Veetikadam
e22df6b974 added library of Consts.js 2020-12-08 14:40:55 +05:30
Zainuden Veetikadam
c23434512d changes to constant file 2020-12-08 14:38:39 +05:30
Zainuden Veetikadam
78d65b04b4 deleted Enums.js 2020-12-08 10:52:18 +05:30
Zainuden Veetikadam
b7f16dbb80 changes 2020-12-07 17:18:58 +05:30
Zainuden Veetikadam
d71ab3132d changes to include validation 2020-12-07 17:07:39 +05:30
Zainuden Veetikadam
dbd3c8ef8d chnages to include enum and valdiation 2020-12-05 15:03:22 +05:30
Zainuden Veetikadam
61f3da0eb1 changes as per PR comment 2020-12-05 14:21:52 +05:30
Zainuden Veetikadam
b5bd602263 az gov cloud changes 2020-11-30 15:47:39 +05:30
Zainuden Veetikadam
8476f79486 changes to Azure cloud 2020-11-30 15:19:18 +05:30
Zainuden Veetikadam
ebd3ce082b added support for Azure Gov cloud 2020-11-30 15:15:50 +05:30
7969 changed files with 1715569 additions and 8305 deletions

1
.github/CODEOWNERS vendored
View File

@@ -1 +0,0 @@
@kaverma @kanika1894 @BALAGA-GAYATRI @pulkitaggarwl

View File

@@ -1,10 +0,0 @@
---
name: Bug Report / Feature Request
about: Create a report to help us improve
title: ''
labels: need-to-triage
assignees: ''
---

View File

@@ -1,4 +0,0 @@
label-alias:
bug: 'bug'
feature_request: 'enhancement'
question: 'question'

View File

@@ -1,92 +0,0 @@
#This workflow is used to test azure login action for CLI edge build. Visit, https://github.com/Azure/azure-cli#edge-builds for more details.
name: Run Azure Login Canary Test
on:
workflow_dispatch:
schedule:
- cron: ' 0 8 * * *'
permissions:
id-token: write
contents: read
jobs:
az-login-test:
runs-on: ubuntu-latest
steps:
- name : Check Az version before installing
run: az --version
- name: Installing Az CLI Edge build
run: |
cd ../..
CWD="$(pwd)"
python3 -m venv canary-venv
. canary-venv/bin/activate
echo "***********activated virual environment**********"
python3 -m pip install --upgrade pip
echo "***************started installing cli edge build******************"
pip3 install -q --upgrade --pre azure-cli --extra-index-url https://azurecliprod.blob.core.windows.net/edge --no-cache-dir --upgrade-strategy=eager
echo "***************installed cli Edge build*******************"
echo "$CWD/canary-venv/bin" >> $GITHUB_PATH
az --version
- name: Check out repository
uses: actions/checkout@v4
- name: 'Az CLI login with subscription'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- run: |
az account show --output none
- name: 'Az CLI login without subscription'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
allow-no-subscriptions: true
- run: |
az account show --output none
- name: 'Az CLI login with subscription OIDC'
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENTID }}
tenant-id: ${{ secrets.AZURE_TENANTID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID }}
- run: |
az account show --output none
- name: 'Az CLI login without subscription OIDC'
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENTID }}
tenant-id: ${{ secrets.AZURE_TENANTID }}
allow-no-subscriptions: true
- 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}}

View File

@@ -1,129 +0,0 @@
name: Run Azure Login Integration Tests
on:
workflow_dispatch:
schedule:
- cron: '0 */3 * * *'
permissions:
id-token: write
contents: write
jobs:
az-login-test-non-oidc:
runs-on: ubuntu-latest
# continue-on-error: true
steps:
- name: 'Az CLI login with subscription'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- run: |
az account show --output none
az vm list --output none
- name: 'Az CLI login without subscription'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
allow-no-subscriptions: true
- run: |
az account show --output none
- name: 'Azure PowerShell login with subscription'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
enable-AzPSSession: true
- uses: azure/powershell@v1
with:
inlineScript: "(Get-AzContext).Environment.Name"
azPSVersion: "latest"
- name: 'Azure PowerShell login without subscription'
uses: azure/login@v1
with:
creds: ${{secrets.AZURE_CREDENTIALS}}
enable-AzPSSession: true
allow-no-subscriptions: true
- uses: azure/powershell@v1
with:
inlineScript: "(Get-AzContext).Environment.Name"
azPSVersion: "latest"
az-login-test-oidc:
runs-on: ubuntu-latest
# continue-on-error: true
steps:
- name: 'Az CLI login with subscription'
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENTID }}
tenant-id: ${{ secrets.AZURE_TENANTID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID }}
- run: |
az account show --output none
az vm list --output none
- name: 'Az CLI login without subscription'
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENTID }}
tenant-id: ${{ secrets.AZURE_TENANTID }}
allow-no-subscriptions: true
- run: |
az account show --output none
- name: 'Azure PowerShell login with subscription'
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENTID }}
tenant-id: ${{ secrets.AZURE_TENANTID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID }}
enable-AzPSSession: true
- uses: azure/powershell@v1
with:
inlineScript: "(Get-AzContext).Environment.Name"
azPSVersion: "latest"
- name: 'Azure PowerShell login without subscription'
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENTID }}
tenant-id: ${{ secrets.AZURE_TENANTID }}
enable-AzPSSession: true
allow-no-subscriptions: true
- uses: azure/powershell@v1
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}}

View File

@@ -1,368 +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@v4
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 20.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@v1
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@v4
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 20.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@v1
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@v1
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.')
VMTest:
strategy:
matrix:
os: [self_linux, self_windows]
runs-on: ${{ matrix.os }}
environment: Automation test
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v4
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: 'Validate build'
run: |
npm install
npm run build
- name: Login with system-assigned managed identity without auth-type
id: login_14
continue-on-error: true
uses: ./
- 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.')

View File

@@ -1,362 +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, self_linux, self_windows]
runs-on: ${{ matrix.os }}
environment: Automation test
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v4
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 20.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@v1
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
$checkResult = $checkResult -and ((Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG')
$checkResult = $checkResult -and ((Get-AzVM).Count -gt 0)
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@v1
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@v1
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
$checkResult = $checkResult -and ((Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG')
$checkResult = $checkResult -and ((Get-AzVM).Count -gt 0)
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@v4
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 20.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@v1
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
$checkResult = $checkResult -and ((Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG')
$checkResult = $checkResult -and ((Get-AzVM).Count -gt 0)
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@v1
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@v1
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext -ListAvailable).Count -eq 2
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@v1
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
if(-not $checkResult){
throw "Not all checks passed!"
}
VMTest:
strategy:
matrix:
os: [self_linux, self_windows]
runs-on: ${{ matrix.os }}
environment: Automation test
steps:
- name: 'Checking out repo code'
uses: actions/checkout@v4
- name: Set Node.js 20.x for GitHub Action
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: 'Validate build'
run: |
npm install
npm run build
- name: Login with system-assigned managed identity, no subscription-id
uses: ./
with:
auth-type: IDENTITY
allow-no-subscriptions: true
enable-AzPSSession: true
- name: Run Azure Cli
run: |
az account show --output none
- name: Run Azure PowerShell
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
if(-not $checkResult){
throw "Not all checks passed!"
}
- name: Login with system-assigned managed identity, with subscription id
uses: ./
with:
auth-type: IDENTITY
subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID }}
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@v1
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
$checkResult = $checkResult -and ((Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG')
$checkResult = $checkResult -and ((Get-AzVM).Count -gt 0)
if(-not $checkResult){
throw "Not all checks passed!"
}
- name: Login with tenant-level user-assigned managed identity with allow-no-subscriptions
uses: ./
with:
client-id: ${{ secrets.UMI2_CLIENT_ID }}
allow-no-subscriptions: true
auth-type: IDENTITY
enable-AzPSSession: true
- name: Run Azure Cli
run: |
az account show --output none
- name: Run Azure PowerShell
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
if(-not $checkResult){
throw "Not all checks passed!"
}
- name: Login with user-assigned managed identity, subscription-id
uses: ./
with:
client-id: ${{ secrets.UMI1_CLIENT_ID }}
subscription-id: ${{ secrets.UMI1_SUBSCRIPTION_ID }}
auth-type: IDENTITY
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@v1
with:
azPSVersion: "latest"
inlineScript: |
$checkResult = (Get-AzContext).Environment.Name -eq 'AzureCloud'
$checkResult = $checkResult -and ((Get-AzResourceGroup -Name GitHubAction_CI_RG).ResourceGroupName -eq 'GitHubAction_CI_RG')
$checkResult = $checkResult -and ((Get-AzVM).Count -gt 0)
if(-not $checkResult){
throw "Not all checks passed!"
}

View File

@@ -1,71 +0,0 @@
name: pr-check
on:
pull_request_target:
branches:
- master
- 'releases/*'
jobs:
az-login-test:
environment: Automation test
runs-on: windows-latest
steps:
- name: Checkout from PR branch
uses: actions/checkout@v4
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
with:
node-version: 20.x
- name: installing node_modules
run: npm install
- name: Build GitHub Action
run: npm run build
- name: 'Az CLI login with subscription'
uses: ./
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- run: |
az account show --output none
az vm list --output none
- name: 'Az CLI login without subscription'
uses: ./
with:
creds: ${{ secrets.AZURE_CREDENTIALS_NO_SUB }}
allow-no-subscriptions: true
- run: |
az account show --output none
# az vm list --output none
- name: 'Azure PowerShell login with subscription'
uses: ./
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
enable-AzPSSession: true
- uses: azure/powershell@v1
with:
inlineScript: "(Get-AzContext).Environment.Name"
azPSVersion: "latest"
# - name: 'Azure PowerShell login without subscription'
# uses: ./
# with:
# creds: ${{secrets.AZURE_CREDENTIALS_NO_SUB}}
# enable-AzPSSession: true
# allow-no-subscriptions: true
# - uses: azure/powershell@v1
# with:
# inlineScript: "Get-AzContext"
# azPSVersion: "latest"

View File

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

View File

@@ -1,42 +0,0 @@
name: "Code scanning - action"
on:
push:
pull_request:
schedule:
- cron: '0 19 * * 0'
jobs:
CodeQL-Build:
# CodeQL runs on ubuntu-latest and windows-latest
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
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)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

View File

@@ -1,48 +0,0 @@
name: setting-default-labels
# Controls when the action will run.
on:
schedule:
- cron: "0 0/3 * * *"
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/stale@v8
name: Setting issue as idle
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue is idle because it has been open for 14 days with no activity.'
stale-issue-label: 'idle'
days-before-stale: 14
days-before-close: -1
operations-per-run: 100
exempt-issue-labels: 'backlog'
- uses: actions/stale@v8
name: Setting PR as idle
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-pr-message: 'This PR is idle because it has been open for 14 days with no activity.'
stale-pr-label: 'idle'
days-before-stale: 14
days-before-close: -1
operations-per-run: 100
- uses: actions/stale@v8
name: Close issue with no feedback for 20 days
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
close-issue-message: 'This issue has been labeled as `needs-author-feedback` for 20 days with no activity. We will close it for now. If you require additional assistance, please feel free to reopen it with the required information.'
days-before-stale: -1
days-before-close: 20
stale-issue-label: 'needs-author-feedback'
only-issue-labels: 'needs-author-feedback'
close-issue-reason: 'completed'
operations-per-run: 100

View File

@@ -1,18 +0,0 @@
name: Markdownlint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: Run Markdownlint
run: |
npm i -g markdownlint-cli2
markdownlint-cli2 "**/*.md"

371
.gitignore vendored
View File

@@ -1,99 +1,330 @@
# Dependency directory ## Ignore Visual Studio temporary files, build results, and
node_modules ## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore # User-specific files
# Logs *.suo
logs *.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log *.log
npm-debug.log* *.vspscc
yarn-debug.log* *.vssscc
yarn-error.log* .builds
lerna-debug.log* *.pidb
*.svclog
*.scc
# Diagnostic reports (https://nodejs.org/api/report.html) # Chutzpah Test files
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json _Chutzpah*
# Runtime data # Visual C++ cache files
pids ipch/
*.pid *.aps
*.seed *.ncb
*.pid.lock *.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Directory for instrumented libs generated by jscoverage/JSCover # Visual Studio profiler
lib-cov *.psess
*.vsp
*.vspx
*.sap
# Coverage directory used by tools like istanbul # Visual Studio Trace Files
coverage *.e2e
*.lcov
# nyc test coverage # TFS 2012 Local Workspace
.nyc_output $tf/
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) # Guidance Automation Toolkit
.grunt *.gpState
# Bower dependency directory (https://bower.io/) # ReSharper is a .NET coding add-in
bower_components _ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# node-waf configuration # JustCode is a .NET coding add-in
.lock-wscript .JustCode
# Compiled binary addons (https://nodejs.org/api/addons.html) # TeamCity is a build add-in
build/Release _TeamCity*
# Dependency directories # DotCover is a Code Coverage Tool
jspm_packages/ *.dotCover
# TypeScript v1 declaration files # AxoCover is a Code Coverage Tool
typings/ .axoCover/*
!.axoCover/settings.json
# TypeScript cache # Visual Studio code coverage results
*.tsbuildinfo *.coverage
*.coveragexml
# Optional npm cache directory # NCrunch
.npm _NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# Optional eslint cache # MightyMoose
.eslintcache *.mm.*
AutoTest.Net/
# Optional REPL history # Web workbench (sass)
.node_repl_history .sass-cache/
# Output of 'npm pack' # Installshield output folder
*.tgz [Ee]xpress/
# Yarn Integrity file # DocProject is a documentation generator add-in
.yarn-integrity DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# dotenv environment variables file # Click-Once directory
.env publish/
.env.test
# parcel-bundler cache (https://parceljs.org/) # Publish Web Output
.cache *.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# next.js build output # Microsoft Azure Web App publish settings. Comment the next line if you want to
.next # checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# nuxt.js build output # NuGet Packages
.nuxt *.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# vuepress build output # Microsoft Azure Build Output
.vuepress/dist csx/
*.build.csdef
# Serverless directories # Microsoft Azure Emulator
.serverless/ ecf/
rcf/
# FuseBox cache # Windows Store app package directories and files
.fusebox/ AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# DynamoDB Local files # Visual Studio cache files
.dynamodb/ # files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# OS metadata # Others
.DS_Store ClientBin/
Thumbs.db ~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Ignore built ts files # Including strong name files can present a security risk
__tests__/runner/* # (https://github.com/github/gitignore/pull/2483#issue-259490424)
lib/**/* #*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/

View File

@@ -1,9 +0,0 @@
{
"config": {
"default": true,
"MD013": false
},
"ignores": [
"SECURITY.md"
]
}

779
README.md
View File

@@ -1,618 +1,161 @@
# Azure Login Action # GitHub Actions Beta Preview for deploying to Azure Stack Hub
- [Azure Login Action](#azure-login-action) ## Automate your GitHub workflows using Azure Actions
- [Input Parameters](#input-parameters)
- [`client-id`](#client-id) [GitHub Actions](https://help.github.com/en/articles/about-github-actions) gives you the flexibility to build an automated software development lifecycle workflow.
- [`subscription-id`](#subscription-id)
- [`tenant-id`](#tenant-id) With [GitHub Actions for Azure](https://github.com/Azure/actions/) you can create workflows that you can set up in your repository to build, test, package, release and **deploy** to Azure.
- [`creds`](#creds)
- [`enable-AzPSSession`](#enable-azpssession) # GitHub Action for Azure Login
- [`environment`](#environment) With the Azure login Action, you can automate your workflow to do an Azure login using [Azure service principal](https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals) and run Az CLI and Azure PowerShell scripts.
- [`allow-no-subscriptions`](#allow-no-subscriptions)
- [`audience`](#audience) By default, only az cli login will be done. In addition to az cli, you can login using Az module to run Azure PowerShell scripts by setting enable-AzPSSession to true.
- [`auth-type`](#auth-type)
- [Workflow Examples](#workflow-examples) Get started today with a [free Azure account](https://azure.com/free/open-source)!
- [Login With OpenID Connect (OIDC) \[Recommended\]](#login-with-openid-connect-oidc-recommended)
- [Login With a Service Principal Secret](#login-with-a-service-principal-secret) This repository contains GitHub Action for [Azure Login](https://github.com/Azure/login/blob/master/action.yml).
- [Login With System-assigned Managed Identity](#login-with-system-assigned-managed-identity)
- [Login With User-assigned Managed Identity](#login-with-user-assigned-managed-identity) ## Sample workflow that uses Azure login action to run az cli on Azure Stack Hub
- [Login to Azure US Government cloud](#login-to-azure-us-government-cloud)
- [Login to Azure Stack Hub](#login-to-azure-stack-hub) ```yaml
- [Login without subscription](#login-without-subscription)
- [Az logout and security hardening](#az-logout-and-security-hardening) # File: .github/workflows/workflow.yml
- [Azure CLI dependency](#azure-cli-dependency)
- [Reference](#reference) on: [push]
- [GitHub Action](#github-action)
- [GitHub Actions for deploying to Azure](#github-actions-for-deploying-to-azure) name: AzureLoginSample
- [Azure CLI Action](#azure-cli-action)
- [Azure PowerShell Action](#azure-powershell-action) jobs:
- [Contributing](#contributing)
build-and-deploy:
With the [Azure Login Action](https://github.com/Azure/login), you can login to Azure and run [Azure CLI](https://learn.microsoft.com/cli/azure/) and [Azure PowerShell](https://learn.microsoft.com/powershell/azure) scripts. runs-on: ubuntu-latest
steps:
Azure Login Action supports different ways of authentication with Azure.
- uses: azure/login@AzureStackSupport-Beta
- Login with OpenID Connect (OIDC) with:
- Login with a Service Principal Secret creds: ${{ secrets.AZURE_CREDENTIALS }}
- Login with System-assigned Managed Identity environment: 'AzureStack'
- Login with User-assigned Managed Identity
- run: |
**We recommend using OIDC based authentication for increased security.** az webapp list --query "[?state=='Running']"
> [!WARNING] ```
> By default, the output of Azure CLI commands is printed to the stdout stream. Without redirecting the stdout stream, contents in it will be stored in the build log of the action. Configure Azure CLI to _not_ show output in the console screen or print in the log by setting the environment variable `AZURE_CORE_OUTPUT` to `none`. If you need the output of a specific command, override the default setting using the argument `--output` with your format of choice. For more information on output options with the Azure CLI, see [Format output](https://learn.microsoft.com/cli/azure/format-output-azure-cli).
## Sample workflow that uses Azure login action to run Azure PowerShell on Azure Stack Hub
** **
```yaml
> [!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). # File: .github/workflows/workflow.yml
## Input Parameters on: [push]
|Parameter Name|Required?|Type|Default Value|Description| name: AzurePowerShellSample
|---|---|---|---|---|
|client-id|false|UUID||the client id of a service principal or a user-assigned managed identity| jobs:
|subscription-id|false|UUID||the login subscription id|
|tenant-id|false|UUID||the login tenant id| build-and-deploy:
|creds|false|string||a json string for login with an Azure service principal| runs-on: ubuntu-latest
|enable-AzPSSession|false|boolean|false|if Azure PowerShell login is enabled| steps:
|environment|false|string|azurecloud|the Azure Cloud environment|
|allow-no-subscriptions|false|boolean|false|if login without subscription is allowed| - name: Login via Az module
|audience|false|string|api://AzureADTokenExchange|the audience to get the JWT ID token from GitHub OIDC provider| uses: azure/login@AzureStackSupport-Beta
|auth-type|false|string|SERVICE_PRINCIPAL|the auth type| with:
creds: ${{secrets.AZURE_CREDENTIALS}}
### `client-id` enable-AzPSSession: true
environment: 'AzureStack'
The input parameter `client-id` specifies the login client id. It could be the client id of a service principal or a user-assigned managed identity.
- name: Run Az CLI script
It's used in login with OpenID Connect (OIDC) and user-assigned managed identity. run: |
az webapp list --query "[?state=='Running']"
It's better to create a GitHub Action secret for this parameter when using it. Refer to [Using secrets in GitHub Actions](https://docs.github.com/actions/security-guides/using-secrets-in-github-actions).
- name: Run Azure PowerShell script
Refer to [Login With OpenID Connect (OIDC)](#login-with-openid-connect-oidc-recommended) and [Login With User-assigned Managed Identity](#login-with-user-assigned-managed-identity) for its usage. uses: azure/powershell@v1
with:
### `subscription-id` azPSVersion: '3.1.0'
inlineScript: |
The input parameter `subscription-id` specifies the login subscription id. Get-AzVM -ResourceGroupName "ActionsDemo"
It's used in login with OpenID Connect (OIDC) and managed identity.
It's better to create a GitHub Action secret for this parameter when using it. Refer to [Using secrets in GitHub Actions](https://docs.github.com/actions/security-guides/using-secrets-in-github-actions). ```
Refer to [Login With OpenID Connect (OIDC)](#login-with-openid-connect-oidc-recommended), [Login With System-assigned Managed Identity](#login-with-system-assigned-managed-identity) and [Login With User-assigned Managed Identity](#login-with-user-assigned-managed-identity) for its usage. Refer [Azure PowerShell](https://github.com/azure/powershell) Github action to run your Azure PowerShell scripts.
### `tenant-id` ## Configure deployment credentials (AAD):
The input parameter `tenant-id` specifies the login tenant id. For any credentials like Azure Service Principal, Publish Profile etc add them as [secrets](https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables) in the GitHub repository and then use them in the workflow.
It's used in login with OpenID Connect (OIDC) and managed identity. The above example uses user-level credentials i.e., Azure Service Principal for deployment.
It's better to create a GitHub Action secret for this parameter when using it. Refer to [Using secrets in GitHub Actions](https://docs.github.com/actions/security-guides/using-secrets-in-github-actions). Follow the steps to configure the secret:
* Define a new secret under your repository settings, Add secret menu
Refer to [Login With OpenID Connect (OIDC)](#login-with-openid-connect-oidc-recommended), [Login With System-assigned Managed Identity](#login-with-system-assigned-managed-identity) and [Login With User-assigned Managed Identity](#login-with-user-assigned-managed-identity) for its usage. * For Azure Stack Hub Environments- Run the following command to set the SQL Management endpoint to 'not supported'
```bash
### `creds`
az cloud update -n {environmentName} --endpoint-sql-management https://notsupported
> [!NOTE]
> ```
> If one of `client-id` and `subscription-id` and `tenant-id` is set, `creds` will be ignored. * Store the output of the below [az cli](https://docs.microsoft.com/en-us/cli/azure/?view=azure-cli-latest) command as the value of secret variable, for example 'AZURE_CREDENTIALS'
```bash
The value of input parameter `creds` is a string in json format, including the following values: az ad sp create-for-rbac --name "myApp" --role contributor \
--scopes /subscriptions/{subscription-id}/resourceGroups/{resource-group} \
```json --sdk-auth
{
"clientSecret": "******", # Replace {subscription-id}, {resource-group} with the subscription, resource group details
"subscriptionId": "******",
"tenantId": "******", # The command should output a JSON object similar to this:
"clientId": "******"
} {
``` "clientId": "<GUID>",
"clientSecret": "<GUID>",
It's used in login with an Azure service principal. "subscriptionId": "<GUID>",
"tenantId": "<GUID>",
It's better to create a GitHub Action secret for this parameter when using it. Refer to [Using secrets in GitHub Actions](https://docs.github.com/actions/security-guides/using-secrets-in-github-actions). (...)
}
Refer to [Login With a Service Principal Secret](#login-with-a-service-principal-secret) for its usage.
```
### `enable-AzPSSession` * Now in the workflow file in your branch: `.github/workflows/workflow.yml` replace the secret in Azure login action with your secret (Refer to the example above)
By default, Azure Login Action only logs in with the Azure CLI. To log in with the Azure PowerShell module, set `enable-AzPSSession` to true.
# Azure Login metadata file
Refer to [Login With OpenID Connect (OIDC)](#login-with-openid-connect-oidc-recommended) for its usage.
```yaml
### `environment`
# action.yml
By default, Azure Login Action connects to the Azure Public Cloud (`AzureCloud`).
# Login to Azure subscription
To login to one of the Azure Government clouds or Azure Stack, set `environment` to one of the supported values `AzureUSGovernment` or `AzureChinaCloud` or `AzureGermanCloud` or `AzureStack`. name: 'Azure Login'
description: 'AuthenticatetoAzureandrunyourAzCLIorAzPowerShellbasedActionsorscripts.github.com/Azure/Actions'
Refer to [Login to Azure US Government cloud](#login-to-azure-us-government-cloud) for its usage. inputs:
creds:
### `allow-no-subscriptions` description: 'Paste output of `az ad sp create-for-rbac` as value of secret variable: AZURE_CREDENTIALS'
required: true
By default, Azure Login Action requires a `subscription-id`. To login to Azure tenants without any subscriptions, set `allow-no-subscriptions` to true. environment:
description: 'Set value to AzureStack for an Azure Stack Hub environment'
Refer to [Login without subscription](#login-without-subscription) for its usage. required: false
default: AzureCloud
### `audience` enable-AzPSSession:
description: 'SetthisvaluetotruetoenableAzurePowerShellLogininadditiontoAzCLIlogin'
Azure Login Action gets the JWT ID token from GitHub OIDC provider when login with OIDC. The default `audience` is `api://AzureADTokenExchange`. Users can specify a custom `audience`. required: false
default: false
### `auth-type` branding:
icon: 'login.svg'
The input parameter `auth-type` specifies the type of authentication. The default value is `SERVICE_PRINCIPAL`. Users can specify it as `IDENTITY` for login with Managed Identity. color: 'blue'
runs:
Refer to [Login With System-assigned Managed Identity](#login-with-system-assigned-managed-identity) and [Login With User-assigned Managed Identity](#login-with-user-assigned-managed-identity) for its usage. using: 'node12'
main: 'lib/main.js'
## Workflow Examples ```
### Login With OpenID Connect (OIDC) [Recommended] # Contributing
> [!NOTE] This project welcomes contributions and suggestions. Most contributions require you to agree to a
> Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
> - Ensure the CLI version is 2.30 or above to support login with OIDC. the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
> - By default, Azure access tokens issued during OIDC based login could have limited validity. Azure access token issued by Service Principal is expected to have an expiration of 1 hour by default. And with Managed Identities, it would be 24 hours. This expiration time is further configurable in Azure. Refer to [access-token lifetime](https://learn.microsoft.com/azure/active-directory/develop/access-tokens#access-token-lifetime) for more details.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
Before you use Azure Login Action with OIDC, you need to configure a federated identity credential on an service principal or a managed identity. a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
- Prepare a service principal for Login with OIDC
- [Create a service principal and assign a role to it](https://learn.microsoft.com/entra/identity-platform/howto-create-service-principal-portal) This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
- [Configure a federated identity credential on an service principal](https://learn.microsoft.com/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azp#github-actions) For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
- Prepare a user-assigned managed identity for Login with OIDC contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
- [Create a user-assigned managed identity and assign a role to it](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/how-manage-user-assigned-managed-identities?pivots=identity-mi-methods-azp#create-a-user-assigned-managed-identity)
- [Configure a federated identity credential on a user-assigned managed identity](https://learn.microsoft.com/entra/workload-id/workload-identity-federation-create-trust-user-assigned-managed-identity?pivots=identity-wif-mi-methods-azp#github-actions-deploying-azure-resources)
After it, create GitHub Action secrets for following values: (Refer to [Using secrets in GitHub Actions](https://docs.github.com/actions/security-guides/using-secrets-in-github-actions).)
- AZURE_CLIENT_ID: the service principal client ID or user-assigned managed identity client ID
- AZURE_SUBSCRIPTION_ID: the subscription ID
- AZURE_TENANT_ID: the tenant ID
Now you can try the workflow to login with OIDC.
> [!NOTE]
>
> In GitHub workflow, you should set `permissions:` with `id-token: write` at workflow level or job level based on whether the OIDC token is allowed be generated for all Jobs or a specific Job.
- **The workflow sample to only run Azure CLI**
```yaml
# File: .github/workflows/workflow.yml
name: Run Azure Login with OIDC
on: [push]
permissions:
id-token: write
contents: read
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Azure login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Azure CLI script
uses: azure/CLI@v1
with:
azcliversion: latest
inlineScript: |
az account show
```
- **The workflow sample to run both Azure CLI and Azure PowerShell**
```yaml
# File: .github/workflows/workflow.yml
name: Run Azure Login with OIDC
on: [push]
permissions:
id-token: write
contents: read
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Azure login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
enable-AzPSSession: true
- name: Azure CLI script
uses: azure/CLI@v1
with:
azcliversion: latest
inlineScript: |
az account show
- name: Azure PowerShell script
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
Get-AzContext
```
### Login With a Service Principal Secret
Before you login a service principal secret, you need to prepare a service principal with a secret.
- [Create a service principal and assign a role to it](https://learn.microsoft.com/entra/identity-platform/howto-create-service-principal-portal)
- [Create a new service principal client secret](https://learn.microsoft.com/entra/identity-platform/howto-create-service-principal-portal#option-3-create-a-new-client-secret)
After it, create a GitHub Action secret `AZURE_CREDENTIALS` with the value like below: (Refer to [Using secrets in GitHub Actions](https://docs.github.com/actions/security-guides/using-secrets-in-github-actions).)
```json
{
"clientSecret": "******",
"subscriptionId": "******",
"tenantId": "******",
"clientId": "******"
}
```
- clientSecret: the service principal client secret
- subscriptionId: the subscription ID
- tenantId: the tenant ID
- clientId: the service principal client ID
Now you can try the workflow to login with a service principal secret.
- **The workflow sample to only run Azure CLI**
```yaml
# File: .github/workflows/workflow.yml
on: [push]
name: Run Azure Login With a Service Principal Secret
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Azure CLI script
uses: azure/CLI@v1
with:
azcliversion: latest
inlineScript: |
az account show
```
- **The workflow sample to run both Azure CLI and Azure PowerShell**
```yaml
# File: .github/workflows/workflow.yml
on: [push]
name: Run Azure Login With a Service Principal Secret
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
enable-AzPSSession: true
- name: Azure CLI script
uses: azure/CLI@v1
with:
azcliversion: latest
inlineScript: |
az account show
- name: Azure PowerShell script
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
Get-AzWebApp
```
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@v1
with:
creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZURE_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}'
```
### Login With System-assigned Managed Identity
> [!NOTE]
>
> "Login With System-assigned Managed Identity" is only supported on GitHub self-hosted runners and the self-hosted runners need to be hosted by Azure virtual machines.
Before you login with system-assigned managed identity, you need to create an Azure virtual machine to host the GitHub self-hosted runner.
- Create an Azure virtual machine
- [Create a Windows virtual machine](https://learn.microsoft.com/azure/virtual-machines/windows/quick-create-portal)
- [Create a Linux virtual machine](https://learn.microsoft.com/azure/virtual-machines/linux/quick-create-portal?tabs=ubuntu)
- [Configure system-assigned managed identity on the Azure virtual machine](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/qs-configure-portal-windows-vm#system-assigned-managed-identity)
- Install required softwares on the Azure virtual machine
- [Install PowerShell](https://learn.microsoft.com/powershell/scripting/install/installing-powershell)
- [Install Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli)
- If you want to run Azure CLI Action, [Install Docker](https://docs.docker.com/engine/install/).
- [Install Azure PowerShell](https://learn.microsoft.com/powershell/azure/install-azure-powershell)
- [Configure the Azure virtual machine as a GitHub self-hosted runner](https://docs.github.com/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners)
After it, create GitHub Action secrets for following values: (Refer to [Using secrets in GitHub Actions](https://docs.github.com/actions/security-guides/using-secrets-in-github-actions).)
- AZURE_SUBSCRIPTION_ID: the Subscription ID
- AZURE_TENANT_ID: the Tenant ID
Now you can try the workflow to login with system-assigned managed identity.
- **The workflow sample to run both Azure CLI and Azure PowerShell**
```yaml
# File: .github/workflows/workflow.yml
name: Run Azure Login with System-assigned Managed Identity
on: [push]
jobs:
build-and-deploy:
runs-on: self-hosted
steps:
- name: Azure login
uses: azure/login@v1
with:
auth-type: IDENTITY
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
enable-AzPSSession: true
# Azure CLI Action only supports linux self-hosted runners for now.
# If you want to execute the Azure CLI script on a windows self-hosted runner, you can execute it directly in `run`.
- name: Azure CLI script
uses: azure/CLI@v1
with:
azcliversion: latest
inlineScript: |
az account show
- name: Azure PowerShell script
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
Get-AzContext
Get-AzResourceGroup
```
### Login With User-assigned Managed Identity
> [!NOTE]
>
> "Login With User-assigned Managed Identity" is only supported on GitHub self-hosted runners and the self-hosted runners need to be hosted by Azure virtual machines.
Before you login with User-assigned managed identity, you need to create an Azure virtual machine to host the GitHub self-hosted runner.
- Create an Azure virtual machine
- [Create a Windows virtual machine](https://learn.microsoft.com/azure/virtual-machines/windows/quick-create-portal)
- [Create a Linux virtual machine](https://learn.microsoft.com/azure/virtual-machines/linux/quick-create-portal?tabs=ubuntu)
- [Create a user-assigned managed identity and assign a role to it](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/how-manage-user-assigned-managed-identities?pivots=identity-mi-methods-azp#create-a-user-assigned-managed-identity)
- [Configure user-assigned managed identity on the Azure virtual machine](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/qs-configure-portal-windows-vm#user-assigned-managed-identity)
- Install required softwares on the Azure virtual machine
- [Install PowerShell](https://learn.microsoft.com/powershell/scripting/install/installing-powershell)
- [Install Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli)
- If you want to run Azure CLI Action, [Install Docker](https://docs.docker.com/engine/install/).
- [Install Azure PowerShell](https://learn.microsoft.com/powershell/azure/install-azure-powershell)
- [Configure the Azure virtual machine as a GitHub self-hosted runner](https://docs.github.com/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners)
After it, create GitHub Action secrets for following values: (Refer to [Using secrets in GitHub Actions](https://docs.github.com/actions/security-guides/using-secrets-in-github-actions).)
- AZURE_CLIENT_ID: the user-assigned managed identity client ID
- AZURE_SUBSCRIPTION_ID: the subscription ID
- AZURE_TENANT_ID: the tenant ID
Now you can try the workflow to login with user-assigned managed identity.
- **The workflow sample to run both Azure CLI and Azure PowerShell**
```yaml
# File: .github/workflows/workflow.yml
name: Run Azure Login with User-assigned Managed Identity
on: [push]
jobs:
build-and-deploy:
runs-on: self-hosted
steps:
- name: Azure login
uses: azure/login@v1
with:
auth-type: IDENTITY
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
enable-AzPSSession: true
# Azure CLI Action only supports linux self-hosted runners for now.
# If you want to execute the Azure CLI script on a windows self-hosted runner, you can execute it directly in `run`.
- name: Azure CLI script
uses: azure/CLI@v1
with:
azcliversion: latest
inlineScript: |
az account show
- name: Azure PowerShell script
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
Get-AzContext
```
### Login to Azure US Government cloud
```yaml
# File: .github/workflows/workflow.yml
on: [push]
name: Login to Azure US Government cloud
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
environment: 'AzureUSGovernment'
enable-AzPSSession: true
```
### Login to Azure Stack Hub
```yaml
# File: .github/workflows/workflow.yml
on: [push]
name: Login to Azure Stack Hub cloud
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
environment: 'AzureStack'
enable-AzPSSession: true
```
Refer to the [Azure Stack Hub Login Action Tutorial](https://learn.microsoft.com/azure-stack/user/ci-cd-github-action-login-cli) for more detailed instructions.
### Login without subscription
Capability has been added to support access to tenants without subscriptions for both OIDC and non-OIDC. This can be useful to run tenant level commands, such as `az ad`. The action accepts an optional parameter `allow-no-subscriptions` which is `false` by default.
```yaml
# File: .github/workflows/workflow.yml
on: [push]
name: Run Azure Login without subscription
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Azure Login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
allow-no-subscriptions: true
enable-AzPSSession: true
- name: Azure CLI script
uses: azure/CLI@v1
with:
azcliversion: latest
inlineScript: |
az account show
- name: Run Azure PowerShell
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
Get-AzContext
```
## Az logout and security hardening
This action doesn't implement ```az logout``` by default at the end of execution. However, there is no way to tamper with the credentials or account information because the GitHub-hosted runner is on a VM that will get re-imaged for every customer run, which deletes everything. But if the runner is self-hosted (not provided by GitHub), it is recommended to manually log out at the end of the workflow, as shown below. More details on security of the runners can be found [here](https://docs.github.com/actions/learn-github-actions/security-hardening-for-github-actions#hardening-for-self-hosted-runners).
> [!WARNING]
> When using self hosted runners it is possible to have multiple runners on a single VM. Currently if your runners share a single user on the VM each runner will share the same credentials. That means in detail that each runner is able to change the permissions of another run. As a workaround we propose to use one single VM user per runner. If you start the runner as a service, do not forget to add the [optional user argument](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service#installing-the-service)
```yaml
- name: Azure CLI script
uses: azure/CLI@v1
with:
inlineScript: |
az logout
az cache purge
az account clear
- name: Azure PowerShell script
uses: azure/powershell@v1
with:
azPSVersion: "latest"
inlineScript: |
Clear-AzContext -Scope Process
Clear-AzContext -Scope CurrentUser
```
## Azure CLI dependency
Internally in this action, we use azure CLI and execute `az login` with the credentials provided through secrets. In order to validate the new azure CLI releases for this action, [canary test workflow](.github/workflows/azure-login-canary.yml) is written which will execute the action on [azure CLI's edge build](https://github.com/Azure/azure-cli#edge-builds) which will fail incase of any breaking change is being introduced in the new upcoming release. The test results can be posted on a slack or teams channel using the corresponding integrations. Incase of a failure, the concern will be raised to [azure-cli](https://github.com/Azure/azure-cli) for taking a necessary action and also the latest CLI installation will be postponed in [Runner VMs](https://github.com/actions/virtual-environments) as well for hosted runner to prevent the workflows failing due to the new CLI changes.
## Reference
### GitHub Action
[GitHub Actions](https://help.github.com/articles/about-github-actions) gives you the flexibility to build an automated software development lifecycle workflow.
### GitHub Actions for deploying to Azure
With [GitHub Actions for Azure](https://github.com/Azure/actions/), you can create workflows that you can set up in your repository to build, test, package, release and **deploy** to Azure.
### Azure CLI Action
Refer to the [Azure CLI](https://github.com/azure/cli) GitHub Action to run your Azure CLI scripts.
### Azure PowerShell Action
Refer to the [Azure PowerShell](https://github.com/azure/powershell) GitHub Action to run your Azure PowerShell scripts.
## Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit <https://cla.opensource.microsoft.com>.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
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.

View File

@@ -1,272 +0,0 @@
import { LoginConfig } from "../src/common/LoginConfig";
describe("LoginConfig Test", () => {
function setEnv(name: string, value: string) {
process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] = value;
}
function cleanEnv() {
for (const envKey in process.env) {
if (envKey.startsWith('INPUT_')) {
delete process.env[envKey]
}
}
}
async function testCreds(creds:any){
setEnv('environment', 'azurecloud');
setEnv('enable-AzPSSession', 'true');
setEnv('allow-no-subscriptions', 'false');
setEnv('auth-type', 'SERVICE_PRINCIPAL');
setEnv('creds', JSON.stringify(creds));
let loginConfig = new LoginConfig();
try{
await loginConfig.initialize();
throw new Error("The last step should fail.");
}catch(error){
expect(error.message.includes("Not all parameters are provided in 'creds'.")).toBeTruthy();
}
}
function testValidateWithErrorMessage(loginConfig:LoginConfig, errorMessage:string){
try{
loginConfig.validate();
throw new Error("The last step should fail.");
}catch(error){
expect(error.message.includes(errorMessage)).toBeTruthy();
}
}
beforeEach(() => {
cleanEnv();
});
test('initialize with creds, lack of clientId', async () => {
let creds1 = {
// 'clientId': 'client-id',
'clientSecret': 'client-secret',
'tenantId': 'tenant-id',
'subscriptionId': 'subscription-id'
}
await testCreds(creds1);
});
test('initialize with creds, lack of clientSecret', async () => {
let creds1 = {
'clientId': 'client-id',
// 'clientSecret': 'client-secret',
'tenantId': 'tenant-id',
'subscriptionId': 'subscription-id'
}
await testCreds(creds1);
});
test('initialize with creds, lack of tenantId', async () => {
let creds1 = {
'clientId': 'client-id',
'clientSecret': 'client-secret',
// 'tenantId': 'tenant-id',
'subscriptionId': 'subscription-id'
}
await testCreds(creds1);
});
test('initialize with creds, lack of subscriptionId, but allowNoSubscriptionsLogin=true', async () => {
let creds1 = {
'clientId': 'client-id',
'clientSecret': 'client-secret',
'tenantId': 'tenant-id',
// 'subscriptionId': 'subscription-id'
}
setEnv('environment', 'azurecloud');
setEnv('enable-AzPSSession', 'true');
setEnv('allow-no-subscriptions', 'true');
setEnv('auth-type', 'SERVICE_PRINCIPAL');
setEnv('creds', JSON.stringify(creds1));
let loginConfig = new LoginConfig();
await loginConfig.initialize();
expect(loginConfig.environment).toBe("azurecloud");
expect(loginConfig.enableAzPSSession).toBeTruthy();
expect(loginConfig.allowNoSubscriptionsLogin).toBeTruthy();
expect(loginConfig.authType).toBe("SERVICE_PRINCIPAL");
expect(loginConfig.servicePrincipalId).toBe("client-id");
expect(loginConfig.servicePrincipalSecret).toBe("client-secret");
expect(loginConfig.tenantId).toBe("tenant-id");
expect(loginConfig.subscriptionId).toBe("");
});
test('initialize with creds', async () => {
let creds = {
'clientId': 'client-id',
'clientSecret': 'client-secret',
'tenantId': 'tenant-id',
'subscriptionId': 'subscription-id'
}
setEnv('environment', 'azurecloud');
setEnv('enable-AzPSSession', 'true');
setEnv('allow-no-subscriptions', 'false');
setEnv('auth-type', 'SERVICE_PRINCIPAL');
setEnv('creds', JSON.stringify(creds));
let loginConfig = new LoginConfig();
await loginConfig.initialize();
expect(loginConfig.environment).toBe("azurecloud");
expect(loginConfig.enableAzPSSession).toBeTruthy();
expect(loginConfig.allowNoSubscriptionsLogin).toBeFalsy();
expect(loginConfig.authType).toBe("SERVICE_PRINCIPAL");
expect(loginConfig.servicePrincipalId).toBe("client-id");
expect(loginConfig.servicePrincipalSecret).toBe("client-secret");
expect(loginConfig.tenantId).toBe("tenant-id");
expect(loginConfig.subscriptionId).toBe("subscription-id");
});
test('initialize with individual parameters', async () => {
setEnv('environment', 'azureusgovernment');
setEnv('enable-AzPSSession', 'false');
setEnv('allow-no-subscriptions', 'true');
setEnv('auth-type', 'SERVICE_PRINCIPAL');
setEnv('tenant-id', 'tenant-id');
setEnv('subscription-id', 'subscription-id');
setEnv('client-id', 'client-id');
let loginConfig = new LoginConfig();
await loginConfig.initialize();
expect(loginConfig.environment).toBe("azureusgovernment");
expect(loginConfig.enableAzPSSession).toBeFalsy();
expect(loginConfig.allowNoSubscriptionsLogin).toBeTruthy();
expect(loginConfig.authType).toBe("SERVICE_PRINCIPAL");
expect(loginConfig.servicePrincipalId).toBe("client-id");
expect(loginConfig.tenantId).toBe("tenant-id");
expect(loginConfig.subscriptionId).toBe("subscription-id");
});
test('initialize with both creds and individual parameters', async () => {
setEnv('environment', 'azureusgovernment');
setEnv('enable-AzPSSession', 'false');
setEnv('allow-no-subscriptions', 'true');
setEnv('auth-type', 'SERVICE_PRINCIPAL');
setEnv('tenant-id', 'tenant-id-aa');
setEnv('subscription-id', 'subscription-id-aa');
setEnv('client-id', 'client-id-aa');
let creds = {
'clientId': 'client-id-bb',
'clientSecret': 'client-secret-bb',
'tenantId': 'tenant-id-bb',
'subscriptionId': 'subscription-id-bb'
}
setEnv('creds', JSON.stringify(creds));
let loginConfig = new LoginConfig();
await loginConfig.initialize();
expect(loginConfig.environment).toBe("azureusgovernment");
expect(loginConfig.enableAzPSSession).toBeFalsy();
expect(loginConfig.allowNoSubscriptionsLogin).toBeTruthy();
expect(loginConfig.authType).toBe("SERVICE_PRINCIPAL");
expect(loginConfig.servicePrincipalId).toBe("client-id-aa");
expect(loginConfig.servicePrincipalSecret).toBeNull();
expect(loginConfig.tenantId).toBe("tenant-id-aa");
expect(loginConfig.subscriptionId).toBe("subscription-id-aa");
});
test('validate with wrong environment', async () => {
setEnv('environment', 'aWrongCloud');
setEnv('enable-AzPSSession', 'false');
setEnv('allow-no-subscriptions', 'true');
setEnv('auth-type', 'SERVICE_PRINCIPAL');
setEnv('tenant-id', 'tenant-id');
setEnv('subscription-id', 'subscription-id');
setEnv('client-id', 'client-id');
let loginConfig = new LoginConfig();
await loginConfig.initialize();
testValidateWithErrorMessage(loginConfig, "Unsupported value 'awrongcloud' for environment is passed.");
});
test('validate with wrong authType', async () => {
setEnv('environment', 'azurestack');
setEnv('enable-AzPSSession', 'false');
setEnv('allow-no-subscriptions', 'true');
setEnv('auth-type', 'SERVICE-PRINCIPAL');
setEnv('tenant-id', 'tenant-id');
setEnv('subscription-id', 'subscription-id');
setEnv('client-id', 'client-id');
let loginConfig = new LoginConfig();
await loginConfig.initialize();
testValidateWithErrorMessage(loginConfig, "Unsupported value 'SERVICE-PRINCIPAL' for authentication type is passed.");
});
test('validate with SERVICE_PRINCIPAL, lack of tenant id', async () => {
setEnv('environment', 'azurestack');
setEnv('enable-AzPSSession', 'false');
setEnv('allow-no-subscriptions', 'true');
setEnv('auth-type', 'SERVICE_PRINCIPAL');
// setEnv('tenant-id', 'tenant-id');
setEnv('subscription-id', 'subscription-id');
setEnv('client-id', 'client-id');
let loginConfig = new LoginConfig();
await loginConfig.initialize();
testValidateWithErrorMessage(loginConfig, "Using auth-type: SERVICE_PRINCIPAL. Not all values are present. Ensure 'client-id' and 'tenant-id' are supplied.");
});
test('validate with SERVICE_PRINCIPAL, lack of client id', async () => {
setEnv('environment', 'azurestack');
setEnv('enable-AzPSSession', 'false');
setEnv('allow-no-subscriptions', 'true');
setEnv('auth-type', 'SERVICE_PRINCIPAL');
setEnv('tenant-id', 'tenant-id');
setEnv('subscription-id', 'subscription-id');
// setEnv('client-id', 'client-id');
let loginConfig = new LoginConfig();
await loginConfig.initialize();
testValidateWithErrorMessage(loginConfig, "Using auth-type: SERVICE_PRINCIPAL. Not all values are present. Ensure 'client-id' and 'tenant-id' are supplied.");
});
test('validate without subscriptionId and allowNoSubscriptionsLogin=false', async () => {
setEnv('environment', 'azurestack');
setEnv('enable-AzPSSession', 'false');
setEnv('allow-no-subscriptions', 'false');
setEnv('auth-type', 'IDENTITY');
// setEnv('subscription-id', 'subscription-id');
let loginConfig = new LoginConfig();
await loginConfig.initialize();
testValidateWithErrorMessage(loginConfig, "Ensure subscriptionId is supplied.");
});
test('validate without subscriptionId and allowNoSubscriptionsLogin=true', async () => {
setEnv('environment', 'azurestack');
setEnv('enable-AzPSSession', 'true');
setEnv('allow-no-subscriptions', 'true');
setEnv('auth-type', 'IDENTITY');
// setEnv('subscription-id', 'subscription-id');
let loginConfig = new LoginConfig();
await loginConfig.initialize();
loginConfig.validate();
expect(loginConfig.environment).toBe("azurestack");
expect(loginConfig.enableAzPSSession).toBeTruthy();
expect(loginConfig.allowNoSubscriptionsLogin).toBeTruthy();
expect(loginConfig.authType).toBe("IDENTITY");
expect(loginConfig.servicePrincipalId).toBe("");
expect(loginConfig.servicePrincipalSecret).toBeNull();
expect(loginConfig.tenantId).toBe("");
expect(loginConfig.subscriptionId).toBe("");
});
});

View File

@@ -1,92 +0,0 @@
import * as os from 'os';
import { AzPSLogin } from '../../src/PowerShell/AzPSLogin';
import { LoginConfig } from '../../src/common/LoginConfig';
import { AzPSConstants, AzPSUtils } from '../../src/PowerShell/AzPSUtils';
let azpsLogin: AzPSLogin;
jest.setTimeout(30000);
beforeAll(() => {
var loginConfig = new LoginConfig();
loginConfig.servicePrincipalId = "servicePrincipalID";
loginConfig.servicePrincipalSecret = "servicePrincipalSecret";
loginConfig.tenantId = "tenantId";
loginConfig.subscriptionId = "subscriptionId";
azpsLogin = new AzPSLogin(loginConfig);
});
afterEach(() => {
jest.restoreAllMocks();
});
describe('Testing login', () => {
let loginSpy;
beforeEach(() => {
loginSpy = jest.spyOn(azpsLogin, 'login');
});
test('ServicePrincipal login should pass', async () => {
loginSpy.mockImplementationOnce(() => Promise.resolve());
await azpsLogin.login();
expect(loginSpy).toHaveBeenCalled();
});
});
describe('Testing set module path', () => {
test('setDefaultPSModulePath should work', () => {
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);
}
if(runner.toLowerCase().startsWith("windows")){
expect(process.env.PSModulePath).toContain(AzPSConstants.DEFAULT_AZ_PATH_ON_WINDOWS);
}
});
});
describe('Testing runPSScript', () => {
test('Get PowerShell Version', async () => {
let script = `try {
$ErrorActionPreference = "Stop"
$WarningPreference = "SilentlyContinue"
$output = @{}
$output['Success'] = $true
$output['Result'] = $PSVersionTable.PSVersion.ToString()
}
catch {
$output['Success'] = $false
$output['Error'] = $_.exception.Message
}
return ConvertTo-Json $output`;
let psVersion: string = await AzPSUtils.runPSScript(script);
expect(psVersion === null).toBeFalsy();
});
test('Get PowerShell Version with Wrong Name', async () => {
let script = `try {
$ErrorActionPreference = "Stop"
$WarningPreference = "SilentlyContinue"
$output = @{}
$output['Success'] = $true
$output['Result'] = $PSVersionTableWrongName.PSVersion.ToString()
}
catch {
$output['Success'] = $false
$output['Error'] = $_.exception.Message
}
return ConvertTo-Json $output`;
try{
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

@@ -1,153 +0,0 @@
import AzPSSCriptBuilder from "../../src/PowerShell/AzPSScriptBuilder";
import { LoginConfig } from "../../src/common/LoginConfig";
describe("Getting AzLogin PS script", () => {
function setEnv(name: string, value: string) {
process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] = value;
}
function cleanEnv() {
for (const envKey in process.env) {
if (envKey.startsWith('INPUT_')) {
delete process.env[envKey]
}
}
}
beforeEach(() => {
cleanEnv();
});
test('getImportLatestModuleScript', () => {
expect(AzPSSCriptBuilder.getImportLatestModuleScript("TestModule")).toContain("(Get-Module -Name 'TestModule' -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Path");
expect(AzPSSCriptBuilder.getImportLatestModuleScript("TestModule")).toContain("Import-Module -Name $latestModulePath");
});
test('getAzPSLoginScript for SP+secret with allowNoSubscriptionsLogin=true', () => {
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': 'subscription-id'
}
setEnv('creds', JSON.stringify(creds));
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
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');
});
});
test('getAzPSLoginScript for SP+secret with allowNoSubscriptionsLogin=true, secret with single-quote', () => {
setEnv('environment', 'azurecloud');
setEnv('enable-AzPSSession', 'true');
setEnv('allow-no-subscriptions', 'true');
setEnv('auth-type', 'SERVICE_PRINCIPAL');
let creds = {
'clientId': 'client-id',
'clientSecret': "client-se'cret",
'tenantId': 'tenant-id',
'subscriptionId': 'subscription-id'
}
setEnv('creds', JSON.stringify(creds));
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
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');
});
});
test('getAzPSLoginScript for SP+secret with allowNoSubscriptionsLogin=false', () => {
setEnv('environment', 'azurecloud');
setEnv('enable-AzPSSession', 'true');
setEnv('allow-no-subscriptions', 'false'); // same as true
setEnv('auth-type', 'SERVICE_PRINCIPAL');
let creds = {
'clientId': 'client-id',
'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(([loginMethod, loginScript]) => {
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');
});
});
test('getAzPSLoginScript for OIDC', () => {
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', 'client-id');
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(([loginMethod, loginScript]) => {
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');
});
});
test('getAzPSLoginScript for System MI', () => {
setEnv('environment', 'azurecloud');
setEnv('enable-AzPSSession', 'true');
setEnv('allow-no-subscriptions', 'false');
setEnv('subscription-id', 'subscription-id');
setEnv('auth-type', 'IDENTITY');
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -Subscription 'subscription-id' | out-null;")).toBeTruthy();
expect(loginMethod).toBe('system-assigned managed identity');
});
});
test('getAzPSLoginScript for System MI without subscription id', () => {
setEnv('environment', 'azurecloud');
setEnv('enable-AzPSSession', 'true');
setEnv('allow-no-subscriptions', 'false');
// setEnv('subscription-id', 'subscription-id');
setEnv('auth-type', 'IDENTITY');
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' | out-null;")).toBeTruthy();
expect(loginMethod).toBe('system-assigned managed identity');
});
});
test('getAzPSLoginScript for user-assigned MI', () => {
setEnv('environment', 'azurecloud');
setEnv('enable-AzPSSession', 'true');
setEnv('allow-no-subscriptions', 'true');
setEnv('auth-type', 'IDENTITY');
setEnv('client-id', 'client-id');
let loginConfig = new LoginConfig();
loginConfig.initialize();
return AzPSSCriptBuilder.getAzPSLoginScript(loginConfig).then(([loginMethod, loginScript]) => {
expect(loginScript.includes("Connect-AzAccount -Identity -Environment 'azurecloud' -AccountId 'client-id' | out-null;")).toBeTruthy();
expect(loginMethod).toBe('user-assigned managed identity');
});
});
});

View File

@@ -0,0 +1,38 @@
import { ServicePrincipalLogin } from '../../src/PowerShell/ServicePrincipalLogin';
jest.mock('../../src/PowerShell/Utilities/Utils');
jest.mock('../../src/PowerShell/Utilities/PowerShellToolRunner');
let spnlogin: ServicePrincipalLogin;
beforeAll(() => {
spnlogin = new ServicePrincipalLogin("servicePrincipalID", "servicePrinicipalkey", "tenantId", "subscriptionId", null, null);
});
afterEach(() => {
jest.restoreAllMocks();
});
describe('Testing initialize', () => {
let initializeSpy;
beforeEach(() => {
initializeSpy = jest.spyOn(spnlogin, 'initialize');
});
test('ServicePrincipalLogin initialize should pass', async () => {
await spnlogin.initialize();
expect(initializeSpy).toHaveBeenCalled();
});
});
describe('Testing login', () => {
let loginSpy;
beforeEach(() => {
loginSpy = jest.spyOn(spnlogin, 'login');
});
test('ServicePrincipal login should pass', async () => {
loginSpy.mockImplementationOnce(() => Promise.resolve());
await spnlogin.login();
expect(loginSpy).toHaveBeenCalled();
});
});

View File

@@ -0,0 +1,45 @@
import Utils from '../../../src/PowerShell/Utilities/Utils';
const version: string = '9.0.0';
const moduleName: string = 'az';
afterEach(() => {
jest.restoreAllMocks();
});
describe('Testing isValidVersion', () => {
const validVersion: string = '1.2.4';
const invalidVersion: string = 'a.bcd';
test('isValidVersion should be true', () => {
expect(Utils.isValidVersion(validVersion)).toBeTruthy();
});
test('isValidVersion should be false', () => {
expect(Utils.isValidVersion(invalidVersion)).toBeFalsy();
});
});
describe('Testing setPSModulePath', () => {
test('PSModulePath with azPSVersion non-empty', () => {
Utils.setPSModulePath(version);
expect(process.env.PSModulePath).toContain(version);
});
test('PSModulePath with azPSVersion empty', () => {
const prevPSModulePath = process.env.PSModulePath;
Utils.setPSModulePath();
expect(process.env.PSModulePath).not.toEqual(prevPSModulePath);
});
});
describe('Testing getLatestModule', () => {
let getLatestModuleSpy;
beforeEach(() => {
getLatestModuleSpy = jest.spyOn(Utils, 'getLatestModule');
});
test('getLatestModule should pass', async () => {
getLatestModuleSpy.mockImplementationOnce((_moduleName: string) => Promise.resolve(version));
await Utils.getLatestModule(moduleName);
expect(getLatestModuleSpy).toHaveBeenCalled();
});
});

View File

@@ -1,44 +1,21 @@
# Login to Azure subscription # Login to Azure subscription
name: 'Azure Login' name: 'Azure Login'
description: 'Authenticate to Azure and run your Azure CLI or Azure PowerShell based actions or scripts.' description: 'AuthenticatetoAzureandrunyourAzCLIorAzPowerShellbasedActionsorscripts.github.com/Azure/Actions'
inputs: inputs:
creds: creds:
description: 'Paste output of `az ad sp create-for-rbac` as value of secret variable: AZURE_CREDENTIALS' description: 'Paste output of `az ad sp create-for-rbac` as value of secret variable: AZURE_CREDENTIALS'
required: false required: true
client-id:
description: 'ClientId of the Azure Service principal created.'
required: false
tenant-id:
description: 'TenantId of the Azure Service principal created.'
required: false
subscription-id:
description: 'Azure subscriptionId'
required: false
enable-AzPSSession: enable-AzPSSession:
description: 'Set this value to true to enable Azure PowerShell Login in addition to Azure CLI login' description: 'SetthisvaluetotruetoenableAzurePowerShellLogininadditiontoAzCLIlogin'
required: false required: false
default: false default: false
environment: environment:
description: 'Name of the environment. Supported values are azurecloud, azurestack, azureusgovernment, azurechinacloud, azuregermancloud. Default being azurecloud' description: 'Name of the environment. Supported values are AzureStack, AzureCloud. Default being AzureCloud'
required: false required: false
default: azurecloud default: AzureCloud
allow-no-subscriptions:
description: 'Set this value to true to enable support for accessing tenants without subscriptions'
required: false
default: false
audience:
description: 'Provide audience field for access-token. Default value is api://AzureADTokenExchange'
required: false
default: 'api://AzureADTokenExchange'
auth-type:
description: 'The type of authentication. Supported values are SERVICE_PRINCIPAL, IDENTITY. Default value is SERVICE_PRINCIPAL'
required: false
default: 'SERVICE_PRINCIPAL'
branding: branding:
icon: 'login.svg' icon: 'login.svg'
color: 'blue' color: 'blue'
runs: runs:
using: 'node20' using: 'node12'
pre: 'lib/cleanup.js'
main: 'lib/main.js' main: 'lib/main.js'
post: 'lib/cleanup.js'

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Constants {
}
exports.default = Constants;
Constants.prefix = "az_";
Constants.moduleName = "Az.Accounts";
Constants.versionPattern = /[0-9]\.[0-9]\.[0-9]/;
Constants.AzureCloud = "AzureCloud";
Constants.Subscription = "Subscription";
Constants.ServicePrincipal = "ServicePrincipal";
Constants.Success = "Success";
Constants.Error = "Error";
Constants.AzVersion = "AzVersion";

View File

@@ -0,0 +1,75 @@
"use strict";
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 __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const Utils_1 = __importDefault(require("./Utilities/Utils"));
const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellToolRunner"));
const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder"));
const Constants_1 = __importDefault(require("./Constants"));
class ServicePrincipalLogin {
constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, environment, resourceManagerEndpointUrl) {
this.servicePrincipalId = servicePrincipalId;
this.servicePrincipalKey = servicePrincipalKey;
this.tenantId = tenantId;
this.subscriptionId = subscriptionId;
this.environment = environment;
this.resourceManagerEndpointUrl = resourceManagerEndpointUrl;
}
initialize() {
return __awaiter(this, void 0, void 0, function* () {
Utils_1.default.setPSModulePath();
const azLatestVersion = yield Utils_1.default.getLatestModule(Constants_1.default.moduleName);
core.debug(`Az Module version used: ${azLatestVersion}`);
Utils_1.default.setPSModulePath(`${Constants_1.default.prefix}${azLatestVersion}`);
});
}
login() {
return __awaiter(this, void 0, void 0, function* () {
let output = "";
const options = {
listeners: {
stdout: (data) => {
output += data.toString();
}
}
};
const args = {
servicePrincipalId: this.servicePrincipalId,
servicePrincipalKey: this.servicePrincipalKey,
subscriptionId: this.subscriptionId,
environment: this.environment,
scopeLevel: ServicePrincipalLogin.scopeLevel,
resourceManagerEndpointUrl: this.resourceManagerEndpointUrl,
};
const script = new ScriptBuilder_1.default().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args);
yield PowerShellToolRunner_1.default.init();
yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(script, options);
const result = JSON.parse(output.trim());
if (!(Constants_1.default.Success in result)) {
throw new Error(`Azure PowerShell login failed with error: ${result[Constants_1.default.Error]}`);
}
console.log(`Azure PowerShell session successfully initialized`);
});
}
}
exports.ServicePrincipalLogin = ServicePrincipalLogin;
ServicePrincipalLogin.scopeLevel = Constants_1.default.Subscription;
ServicePrincipalLogin.scheme = Constants_1.default.ServicePrincipal;

View File

@@ -0,0 +1,35 @@
"use strict";
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 __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const io = __importStar(require("@actions/io"));
const exec = __importStar(require("@actions/exec"));
class PowerShellToolRunner {
static init() {
return __awaiter(this, void 0, void 0, function* () {
if (!PowerShellToolRunner.psPath) {
PowerShellToolRunner.psPath = yield io.which("pwsh", true);
}
});
}
static executePowerShellScriptBlock(scriptBlock, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
yield exec.exec(`"${PowerShellToolRunner.psPath}" -Command`, [scriptBlock], options);
});
}
}
exports.default = PowerShellToolRunner;

View File

@@ -0,0 +1,65 @@
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const Constants_1 = __importDefault(require("../Constants"));
class ScriptBuilder {
constructor() {
this.script = "";
}
getAzPSLoginScript(scheme, tenantId, args) {
let command = `Clear-AzContext -Scope Process;
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`;
if (scheme === Constants_1.default.ServicePrincipal) {
if (args.environment.toLowerCase() == "azurestack") {
command += `Add-AzEnvironment -Name ${args.environment} -ARMEndpoint ${args.resourceManagerEndpointUrl} | out-null;`;
}
command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \
-Environment '${args.environment}' | out-null;`;
if (args.scopeLevel === Constants_1.default.Subscription) {
command += `Set-AzContext -SubscriptionId '${args.subscriptionId}' -TenantId '${tenantId}' | out-null;`;
}
}
this.script += `try {
$ErrorActionPreference = "Stop"
$WarningPreference = "SilentlyContinue"
$output = @{}
${command}
$output['${Constants_1.default.Success}'] = "true"
}
catch {
$output['${Constants_1.default.Error}'] = $_.exception.Message
}
return ConvertTo-Json $output`;
core.debug(`Azure PowerShell Login Script: ${this.script}`);
return this.script;
}
getLatestModuleScript(moduleName) {
const command = `Get-Module -Name ${moduleName} -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1`;
this.script += `try {
$ErrorActionPreference = "Stop"
$WarningPreference = "SilentlyContinue"
$output = @{}
$data = ${command}
$output['${Constants_1.default.AzVersion}'] = $data.Version.ToString()
$output['${Constants_1.default.Success}'] = "true"
}
catch {
$output['${Constants_1.default.Error}'] = $_.exception.Message
}
return ConvertTo-Json $output`;
core.debug(`GetLatestModuleScript: ${this.script}`);
return this.script;
}
}
exports.default = ScriptBuilder;

View File

@@ -0,0 +1,80 @@
"use strict";
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 __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const os = __importStar(require("os"));
const Constants_1 = __importDefault(require("../Constants"));
const ScriptBuilder_1 = __importDefault(require("./ScriptBuilder"));
const PowerShellToolRunner_1 = __importDefault(require("./PowerShellToolRunner"));
class Utils {
/**
* Add the folder path where Az modules are present to PSModulePath based on runner
* @param azPSVersion
* If azPSVersion is empty, folder path in which all Az modules are present are set
* If azPSVersion is not empty, folder path of exact Az module version is set
*/
static setPSModulePath(azPSVersion = "") {
let modulePath = "";
const runner = process.env.RUNNER_OS || os.type();
switch (runner.toLowerCase()) {
case "linux":
modulePath = `/usr/share/${azPSVersion}:`;
break;
case "windows":
case "windows_nt":
modulePath = `C:\\Modules\\${azPSVersion};`;
break;
case "macos":
case "darwin":
throw new Error(`OS not supported`);
default:
throw new Error(`Unknown os: ${runner.toLowerCase()}`);
}
process.env.PSModulePath = `${modulePath}${process.env.PSModulePath}`;
}
static getLatestModule(moduleName) {
return __awaiter(this, void 0, void 0, function* () {
let output = "";
const options = {
listeners: {
stdout: (data) => {
output += data.toString();
}
}
};
yield PowerShellToolRunner_1.default.init();
yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(new ScriptBuilder_1.default()
.getLatestModuleScript(moduleName), options);
const result = JSON.parse(output.trim());
if (!(Constants_1.default.Success in result)) {
throw new Error(result[Constants_1.default.Error]);
}
const azLatestVersion = result[Constants_1.default.AzVersion];
if (!Utils.isValidVersion(azLatestVersion)) {
throw new Error(`Invalid AzPSVersion: ${azLatestVersion}`);
}
return azLatestVersion;
});
}
static isValidVersion(version) {
return !!version.match(Constants_1.default.versionPattern);
}
}
exports.default = Utils;

141
lib/main.js Normal file
View File

@@ -0,0 +1,141 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (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 crypto = __importStar(require("crypto"));
const exec = __importStar(require("@actions/exec"));
const io = __importStar(require("@actions/io"));
const actions_secret_parser_1 = require("actions-secret-parser");
const ServicePrincipalLogin_1 = require("./PowerShell/ServicePrincipalLogin");
var azPath;
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 {
// Set user agent variable
var isAzCLISuccess = false;
let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex');
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);
azPath = yield io.which("az", true);
yield executeAzCliCommand("--version");
let azureSupportedCloudName = new Set(["azureusgovernment", "azurechinacloud", "azuregermancloud", "azurecloud", "azurestack"]);
let creds = core.getInput('creds', { required: true });
let secrets = new actions_secret_parser_1.SecretParser(creds, actions_secret_parser_1.FormatType.JSON);
let servicePrincipalId = secrets.getSecret("$.clientId", false);
let servicePrincipalKey = secrets.getSecret("$.clientSecret", true);
let tenantId = secrets.getSecret("$.tenantId", false);
let subscriptionId = secrets.getSecret("$.subscriptionId", false);
let resourceManagerEndpointUrl = secrets.getSecret("$.resourceManagerEndpointUrl", false);
let environment = core.getInput("environment").toLowerCase();
const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true";
if (!servicePrincipalId || !servicePrincipalKey || !tenantId || !subscriptionId) {
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret, tenantId and subscriptionId are supplied.");
}
if (!azureSupportedCloudName.has(environment)) {
throw new Error("Unsupported value for environment is passed.The list of supported values for environment are azureusgovernment', azurechinacloud, azuregermancloud, azurecloud or azurestack");
}
// Attempting Az cli login
if (environment == "azurestack") {
if (!resourceManagerEndpointUrl) {
throw new Error("resourceManagerEndpointUrl is a required parameter when environment is defined.");
}
console.log(`Unregistering cloud: "${environment}" first if it exists`);
try {
yield executeAzCliCommand(`cloud set -n AzureCloud`, true);
yield executeAzCliCommand(`cloud unregister -n "${environment}"`, false);
}
catch (error) {
console.log(`Ignore cloud not registered error: "${error}"`);
}
console.log(`Registering cloud: "${environment}" with ARM endpoint: "${resourceManagerEndpointUrl}"`);
try {
let baseUri = resourceManagerEndpointUrl;
if (baseUri.endsWith('/')) {
baseUri = baseUri.substring(0, baseUri.length - 1); // need to remove trailing / from resourceManagerEndpointUrl to correctly derive suffixes below
}
let suffixKeyvault = ".vault" + baseUri.substring(baseUri.indexOf('.')); // keyvault suffix starts with .
let suffixStorage = baseUri.substring(baseUri.indexOf('.') + 1); // storage suffix starts without .
let profileVersion = "2019-03-01-hybrid";
yield executeAzCliCommand(`cloud register -n "${environment}" --endpoint-resource-manager "${resourceManagerEndpointUrl}" --suffix-keyvault-dns "${suffixKeyvault}" --suffix-storage-endpoint "${suffixStorage}" --profile "${profileVersion}"`, false);
}
catch (error) {
core.error(`Error while trying to register cloud "${environment}": "${error}"`);
}
console.log(`Done registering cloud: "${environment}"`);
}
yield executeAzCliCommand(`cloud set -n "${environment}"`, false);
console.log(`Done setting cloud: "${environment}"`);
isAzCLISuccess = true;
if (enableAzPSSession) {
// Attempting Az PS login
console.log(`Running Azure PS Login`);
const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, environment, resourceManagerEndpointUrl);
yield spnlogin.initialize();
yield spnlogin.login();
}
else {
// login using az cli
yield executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
yield executeAzCliCommand(`account set --subscription "${subscriptionId}"`, true);
}
console.log("Login successful.");
}
catch (error) {
if (!isAzCLISuccess) {
core.error("Az CLI Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows");
}
else {
core.error(`Azure PowerShell Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"`);
}
core.setFailed(error);
}
finally {
// Reset AZURE_HTTP_USER_AGENT
core.exportVariable('AZURE_HTTP_USER_AGENT', prefix);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv);
}
});
}
function executeAzCliCommand(command, silent) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield exec.exec(`"${azPath}" ${command}`, [], { silent: !!silent });
}
catch (error) {
throw new Error(error);
}
});
}
main();

15
node_modules/.bin/acorn generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../acorn/bin/acorn" "$@"
ret=$?
else
node "$basedir/../acorn/bin/acorn" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/acorn.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\acorn\bin\acorn" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/acorn.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../acorn/bin/acorn" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../acorn/bin/acorn" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/atob generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../atob/bin/atob.js" "$@"
ret=$?
else
node "$basedir/../atob/bin/atob.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/atob.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\atob\bin\atob.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/atob.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../atob/bin/atob.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../atob/bin/atob.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/escodegen generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../escodegen/bin/escodegen.js" "$@"
ret=$?
else
node "$basedir/../escodegen/bin/escodegen.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/escodegen.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\escodegen\bin\escodegen.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/escodegen.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../escodegen/bin/escodegen.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../escodegen/bin/escodegen.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/esgenerate generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../escodegen/bin/esgenerate.js" "$@"
ret=$?
else
node "$basedir/../escodegen/bin/esgenerate.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/esgenerate.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\escodegen\bin\esgenerate.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/esgenerate.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../escodegen/bin/esgenerate.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../escodegen/bin/esgenerate.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/esparse generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../esprima/bin/esparse.js" "$@"
ret=$?
else
node "$basedir/../esprima/bin/esparse.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/esparse.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\esprima\bin\esparse.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/esparse.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../esprima/bin/esparse.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../esprima/bin/esparse.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/esvalidate generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../esprima/bin/esvalidate.js" "$@"
ret=$?
else
node "$basedir/../esprima/bin/esvalidate.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/esvalidate.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\esprima\bin\esvalidate.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/esvalidate.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../esprima/bin/esvalidate.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../esprima/bin/esvalidate.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/import-local-fixture generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../import-local/fixtures/cli.js" "$@"
ret=$?
else
node "$basedir/../import-local/fixtures/cli.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/import-local-fixture.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\import-local\fixtures\cli.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/import-local-fixture.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../import-local/fixtures/cli.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../import-local/fixtures/cli.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/is-ci generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../is-ci/bin.js" "$@"
ret=$?
else
node "$basedir/../is-ci/bin.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/is-ci.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\is-ci\bin.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/is-ci.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../is-ci/bin.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../is-ci/bin.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/jest generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../jest/bin/jest.js" "$@"
ret=$?
else
node "$basedir/../jest/bin/jest.js" "$@"
ret=$?
fi
exit $ret

15
node_modules/.bin/jest-runtime generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../jest-runtime/bin/jest-runtime.js" "$@"
ret=$?
else
node "$basedir/../jest-runtime/bin/jest-runtime.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/jest-runtime.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\jest-runtime\bin\jest-runtime.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/jest-runtime.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../jest-runtime/bin/jest-runtime.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../jest-runtime/bin/jest-runtime.js" $args
$ret=$LASTEXITCODE
}
exit $ret

17
node_modules/.bin/jest.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\jest\bin\jest.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/jest.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../jest/bin/jest.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../jest/bin/jest.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/js-yaml generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../js-yaml/bin/js-yaml.js" "$@"
ret=$?
else
node "$basedir/../js-yaml/bin/js-yaml.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/js-yaml.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\js-yaml\bin\js-yaml.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/js-yaml.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/jsesc generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../jsesc/bin/jsesc" "$@"
ret=$?
else
node "$basedir/../jsesc/bin/jsesc" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/jsesc.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\jsesc\bin\jsesc" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/jsesc.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../jsesc/bin/jsesc" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../jsesc/bin/jsesc" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/json5 generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../json5/lib/cli.js" "$@"
ret=$?
else
node "$basedir/../json5/lib/cli.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/json5.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\json5\lib\cli.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/json5.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../json5/lib/cli.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../json5/lib/cli.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/mkdirp generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../mkdirp/bin/cmd.js" "$@"
ret=$?
else
node "$basedir/../mkdirp/bin/cmd.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/mkdirp.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\mkdirp\bin\cmd.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/mkdirp.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/node-which generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../which/bin/node-which" "$@"
ret=$?
else
node "$basedir/../which/bin/node-which" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/node-which.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\which\bin\node-which" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/node-which.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../which/bin/node-which" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../which/bin/node-which" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/parser generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../@babel/parser/bin/babel-parser.js" "$@"
ret=$?
else
node "$basedir/../@babel/parser/bin/babel-parser.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/parser.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\@babel\parser\bin\babel-parser.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/parser.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../@babel/parser/bin/babel-parser.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../@babel/parser/bin/babel-parser.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/rimraf generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../rimraf/bin.js" "$@"
ret=$?
else
node "$basedir/../rimraf/bin.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/rimraf.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\rimraf\bin.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/rimraf.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../rimraf/bin.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../rimraf/bin.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/sane generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../sane/src/cli.js" "$@"
ret=$?
else
node "$basedir/../sane/src/cli.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/sane.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\sane\src\cli.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/sane.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../sane/src/cli.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../sane/src/cli.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/semver generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../semver/bin/semver.js" "$@"
ret=$?
else
node "$basedir/../semver/bin/semver.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/semver.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\semver\bin\semver.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/semver.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../semver/bin/semver.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/sshpk-conv generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../sshpk/bin/sshpk-conv" "$@"
ret=$?
else
node "$basedir/../sshpk/bin/sshpk-conv" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/sshpk-conv.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\sshpk\bin\sshpk-conv" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/sshpk-conv.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-conv" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../sshpk/bin/sshpk-conv" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/sshpk-sign generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../sshpk/bin/sshpk-sign" "$@"
ret=$?
else
node "$basedir/../sshpk/bin/sshpk-sign" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/sshpk-sign.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\sshpk\bin\sshpk-sign" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/sshpk-sign.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-sign" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../sshpk/bin/sshpk-sign" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/sshpk-verify generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../sshpk/bin/sshpk-verify" "$@"
ret=$?
else
node "$basedir/../sshpk/bin/sshpk-verify" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/sshpk-verify.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\sshpk\bin\sshpk-verify" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/sshpk-verify.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-verify" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../sshpk/bin/sshpk-verify" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/ts-jest generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../ts-jest/cli.js" "$@"
ret=$?
else
node "$basedir/../ts-jest/cli.js" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/ts-jest.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\ts-jest\cli.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/ts-jest.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../ts-jest/cli.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../ts-jest/cli.js" $args
$ret=$LASTEXITCODE
}
exit $ret

15
node_modules/.bin/tsc generated vendored Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
ret=$?
else
node "$basedir/../typescript/bin/tsc" "$@"
ret=$?
fi
exit $ret

17
node_modules/.bin/tsc.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\..\typescript\bin\tsc" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/tsc.ps1 generated vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../typescript/bin/tsc" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../typescript/bin/tsc" $args
$ret=$LASTEXITCODE
}
exit $ret

Some files were not shown because too many files have changed in this diff Show More