This repository has been archived by the owner on Apr 22, 2022. It is now read-only.
forked from Azure/powershell
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Azure PowerShell - Script Execution (Azure#1)
* initial commit * Create main.yml * Update main.yml * added action.yml * added action.yml * added action.yml * Delete main.yml * removed node_modules * changes in .gitignore * changes in PowerShellToolRunner * Added changes for review comments * added inputs in action.yml * changes in package.json * added review comments * Update action.yml * Update action.yml * fix in ScriptRunner.ts * changes in URL * added review comments * changes for review comments * added args in PowerShellToolRunner * changes in PowerShellToolRunner * fixed action.yml * removed debug logs * changes in main
- Loading branch information
Showing
20 changed files
with
993 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Azure PowerShell Action | ||
name: 'Azure PowerShell Action' | ||
description: 'Automate your GitHub workflows using Azure PowerShell scripts.' | ||
inputs: | ||
inlineScript: | ||
description: 'Specify the Az PowerShell script here.' | ||
required: true | ||
azPSVersion: | ||
description: 'Azure PS version to be used to execute the script, example: 1.8.0, 2.8.0, 3.4.0. To use the latest version, specify "latest".' | ||
required: true | ||
errorActionPreference: | ||
description: 'Select the value of the ErrorActionPreference variable for executing the script. Options: stop, continue, silentlyContinue. Default is Stop.' | ||
required: false | ||
default: 'Stop' | ||
failOnStandardError: | ||
description: 'If this is true, this task will fail if any errors are written to the error pipeline, or if any data is written to the Standard Error stream.' | ||
required: false | ||
default: 'false' | ||
branding: | ||
icon: 'login.svg' | ||
color: 'blue' | ||
runs: | ||
using: 'node12' | ||
main: 'lib/main.js' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class Constants { | ||
} | ||
exports.default = Constants; | ||
Constants.prefix = "az_"; | ||
Constants.moduleName = "Az"; | ||
Constants.versionPattern = /[0-9]\.[0-9]\.[0-9]/; | ||
Constants.Success = "Success"; | ||
Constants.Error = "Error"; | ||
Constants.AzVersion = "AzVersion"; | ||
Constants.versionExists = "versionExists"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
"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 Constants_1 = __importDefault(require("./Constants")); | ||
class InitializeAzure { | ||
static importAzModule(azPSVersion) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
Utils_1.default.setPSModulePath(); | ||
if (azPSVersion === "latest") { | ||
azPSVersion = yield Utils_1.default.getLatestModule(Constants_1.default.moduleName); | ||
} | ||
else { | ||
yield Utils_1.default.checkModuleVersion(Constants_1.default.moduleName, azPSVersion); | ||
} | ||
core.debug(`Az Module version used: ${azPSVersion}`); | ||
Utils_1.default.setPSModulePath(`${Constants_1.default.prefix}${azPSVersion}`); | ||
}); | ||
} | ||
} | ||
exports.default = InitializeAzure; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
"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 FileUtils_1 = __importDefault(require("./Utilities/FileUtils")); | ||
const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellToolRunner")); | ||
const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder")); | ||
class ScriptRunner { | ||
constructor(inlineScript, errorActionPreference, failOnStandardErr) { | ||
this.inlineScript = inlineScript; | ||
this.errorActionPreference = errorActionPreference; | ||
this.failOnStandardErr = failOnStandardErr; | ||
} | ||
executeFile() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const error = []; | ||
const options = { | ||
listeners: { | ||
stderr: (data) => { | ||
if (error.length < 10) { | ||
// Truncate to at most 1000 bytes | ||
if (data.length > 1000) { | ||
error.push(`${data.toString('utf8', 0, 1000)}<truncated>`); | ||
} | ||
else { | ||
error.push(data.toString('utf8')); | ||
} | ||
} | ||
else if (error.length === 10) { | ||
error.push('Additional writes to stderr truncated'); | ||
} | ||
} | ||
} | ||
}; | ||
const scriptToExecute = new ScriptBuilder_1.default().getInlineScriptFile(this.inlineScript, this.errorActionPreference); | ||
ScriptRunner.filePath = yield FileUtils_1.default.createScriptFile(scriptToExecute); | ||
core.debug(`script file to run: ${ScriptRunner.filePath}`); | ||
yield PowerShellToolRunner_1.default.init(); | ||
const exitCode = yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(ScriptRunner.filePath, options); | ||
if (exitCode !== 0) { | ||
core.setOutput(`Azure PowerShell exited with code:`, exitCode.toString()); | ||
if (this.failOnStandardErr) { | ||
error.forEach((err) => { | ||
core.error(err); | ||
}); | ||
throw new Error(`Standard error stream contains one or more lines`); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
exports.default = ScriptRunner; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
"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 fs = __importStar(require("fs")); | ||
const os = __importStar(require("os")); | ||
const path = __importStar(require("path")); | ||
const core = __importStar(require("@actions/core")); | ||
const uuid_1 = require("uuid"); | ||
class FileUtils { | ||
static createScriptFile(inlineScript) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const fileName = FileUtils.getFileName(); | ||
const filePath = path.join(FileUtils.tempDirectory, fileName); | ||
fs.writeFileSync(filePath, inlineScript, 'utf-8'); | ||
return filePath; | ||
}); | ||
} | ||
static getFileName() { | ||
return `${uuid_1.v4()}.ps1`; | ||
} | ||
static deleteFile(filePath) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (fs.existsSync(filePath)) { | ||
try { | ||
fs.unlinkSync(filePath); | ||
} | ||
catch (err) { | ||
core.warning(err.toString()); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
exports.default = FileUtils; | ||
FileUtils.tempDirectory = process.env.RUNNER_TEMP || os.tmpdir(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
"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 executePowerShellCommand(command, options = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield exec.exec(`${PowerShellToolRunner.psPath} -NoLogo -NoProfile -NonInteractive -Command ${command}`, [], options); | ||
}); | ||
} | ||
static executePowerShellScriptBlock(scriptBlock, options = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const exitCode = yield exec.exec(`${PowerShellToolRunner.psPath} -NoLogo -NoProfile -NonInteractive -Command`, [scriptBlock], options); | ||
return exitCode; | ||
}); | ||
} | ||
} | ||
exports.default = PowerShellToolRunner; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
"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 os = __importStar(require("os")); | ||
const core = __importStar(require("@actions/core")); | ||
const Constants_1 = __importDefault(require("../Constants")); | ||
class ScriptBuilder { | ||
constructor() { | ||
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; | ||
} | ||
checkModuleVersionScript(moduleName, version) { | ||
const command = `Get-Module -Name ${moduleName} -ListAvailable | Where-Object Version -match ${version}`; | ||
this.script += `try { | ||
$ErrorActionPreference = "Stop" | ||
$WarningPreference = "SilentlyContinue" | ||
$output = @{} | ||
$data = ${command} | ||
$output['${Constants_1.default.versionExists}'] = [string]::IsNullOrEmpty($data) | ||
$output['${Constants_1.default.Success}'] = "true" | ||
} | ||
catch { | ||
$output['${Constants_1.default.Error}'] = $_.exception.Message | ||
} | ||
return ConvertTo-Json $output`; | ||
core.debug(`CheckModuleVersionScript: ${this.script}`); | ||
return this.script; | ||
} | ||
getInlineScriptFile(inlineScript, errorActionPreference) { | ||
this.script = `$ErrorActionPreference = '${errorActionPreference}'${os.EOL}${inlineScript}`; | ||
core.debug(`InlineScript file to be executed: ${this.script}`); | ||
return this.script; | ||
} | ||
} | ||
exports.default = ScriptBuilder; |
Oops, something went wrong.