-
Notifications
You must be signed in to change notification settings - Fork 47
Dynamically download Az module #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
Dynamically download Az module
Pre-baking of Az modules in runners will be refactored such that: 1. Only 1 latest Az module will be available as folder 2. Some high usage module versions will be available as zip based on platform 3. Other versions dynamically downloaded from Azure/az-ps-module-versions repo's releases 4. PSGallery will act as a fallback in case download fail from github releases So to load the correct module from correct source the changes are done.
- Loading branch information
commit 46f5fd064d87934bde00d9923f9c080f9791c9cc
There are no files selected for viewing
This file contains hidden or 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
This file contains hidden or 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,168 @@ | ||
| "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 tc = __importStar(require("@actions/tool-cache")); | ||
| const os = __importStar(require("os")); | ||
| const ArchiveTools_1 = require("./Utilities/ArchiveTools"); | ||
| const FileUtils_1 = __importDefault(require("./Utilities/FileUtils")); | ||
| const Utils_1 = __importDefault(require("./Utilities/Utils")); | ||
| class AzModuleInstaller { | ||
| constructor(version, githubAuth) { | ||
| var _a; | ||
| this.isWin = false; | ||
| this.version = version; | ||
| this.githubAuth = githubAuth; | ||
| this.installResult = { | ||
| moduleSource: "Others", | ||
| isInstalled: false | ||
| }; | ||
| const platform = (_a = (process.env.RUNNER_OS || os.type())) === null || _a === void 0 ? void 0 : _a.toLowerCase(); | ||
| switch (platform) { | ||
| case "windows": | ||
| case "windows_nt": | ||
| this.isWin = true; | ||
| this.moduleContainerPath = "C:\\Modules"; | ||
| this.modulePath = `${this.moduleContainerPath}\\az_${this.version}`; | ||
| break; | ||
| case "linux": | ||
| this.moduleContainerPath = "/usr/share"; | ||
| this.modulePath = `${this.moduleContainerPath}/az_${this.version}`; | ||
| break; | ||
| default: | ||
| throw `OS ${platform} not supported`; | ||
| } | ||
| this.moduleZipPath = `${this.modulePath}.zip`; | ||
| } | ||
| install() { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| if (Utils_1.default.isHostedAgent(this.moduleContainerPath)) { | ||
| yield this.tryInstallingLatest(); | ||
| yield this.tryInstallFromFolder(); | ||
| yield this.tryInstallFromZip(); | ||
| yield this.tryInstallFromGHRelease(); | ||
| yield this.tryInstallFromPSGallery(); | ||
| } | ||
| else { | ||
| core.debug("File layout is not like hosted agent, skippig module install."); | ||
| this.installResult = { | ||
| isInstalled: false, | ||
| moduleSource: "privateAgent" | ||
| }; | ||
| } | ||
| return this.installResult; | ||
| }); | ||
| } | ||
| tryInstallingLatest() { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| if (this.installResult.isInstalled) { | ||
| return; | ||
| } | ||
| if (this.version === "latest") { | ||
| core.debug("Latest selected, will use latest Az module available in agent as folder."); | ||
| this.installResult = { | ||
| isInstalled: true, | ||
| moduleSource: "hostedAgentFolder" | ||
| }; | ||
| } | ||
| }); | ||
| } | ||
| tryInstallFromFolder() { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| if (this.installResult.isInstalled) { | ||
| return; | ||
| } | ||
| if (FileUtils_1.default.pathExists(this.modulePath)) { | ||
| core.debug(`Az ${this.version} present at ${this.modulePath} as folder.`); | ||
| this.installResult = { | ||
| isInstalled: true, | ||
| moduleSource: "hostedAgentFolder" | ||
| }; | ||
| } | ||
| }); | ||
| } | ||
| tryInstallFromZip() { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| if (this.installResult.isInstalled) { | ||
| return; | ||
| } | ||
| if (FileUtils_1.default.pathExists(this.moduleZipPath)) { | ||
| core.debug(`Az ${this.version} present at ${this.moduleZipPath} as zip, expanding it.`); | ||
| yield new ArchiveTools_1.ArchiveTools(this.isWin).unzip(this.moduleZipPath, this.moduleContainerPath); | ||
| yield FileUtils_1.default.deleteFile(this.moduleZipPath); | ||
| this.installResult = { | ||
| isInstalled: true, | ||
| moduleSource: "hostedAgentZip" | ||
| }; | ||
| } | ||
| }); | ||
| } | ||
| tryInstallFromGHRelease() { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| if (this.installResult.isInstalled) { | ||
| return; | ||
| } | ||
| try { | ||
| const downloadUrl = yield this.getDownloadUrlFromGHRelease(); | ||
| core.debug(`Downloading Az ${this.version} from GHRelease using url ${downloadUrl}`); | ||
| yield tc.downloadTool(downloadUrl, this.moduleZipPath, this.githubAuth); | ||
| core.debug(`Expanding Az ${this.version} downloaded at ${this.moduleZipPath} as zip.`); | ||
| yield new ArchiveTools_1.ArchiveTools(this.isWin).unzip(this.moduleZipPath, this.moduleContainerPath); | ||
| yield FileUtils_1.default.deleteFile(this.moduleZipPath); | ||
| this.installResult = { | ||
| isInstalled: true, | ||
| moduleSource: "hostedAgentGHRelease" | ||
| }; | ||
| } | ||
| catch (err) { | ||
| core.debug(err); | ||
| console.log("Download from GHRelease failed, will fallback to PSGallery"); | ||
| } | ||
| }); | ||
| } | ||
| tryInstallFromPSGallery() { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| if (this.installResult.isInstalled) { | ||
| return; | ||
| } | ||
| yield Utils_1.default.saveAzModule(this.version, this.modulePath); | ||
| this.installResult = { | ||
| isInstalled: true, | ||
| moduleSource: "hostedAgentPSGallery" | ||
| }; | ||
| }); | ||
| } | ||
| getDownloadUrlFromGHRelease() { | ||
| var _a; | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| core.debug("Getting versions manifest from GHRelease."); | ||
| const releases = yield tc.getManifestFromRepo("Azure", "az-ps-module-versions", this.githubAuth, "main"); | ||
| core.debug(JSON.stringify(releases)); | ||
| const releaseInfo = (_a = releases.filter(release => release.version === this.version)) === null || _a === void 0 ? void 0 : _a[0]; | ||
| let downloadUrl = null; | ||
| if (releaseInfo && releaseInfo.files.length > 0) { | ||
| downloadUrl = releaseInfo.files[0].download_url; | ||
| } | ||
| return downloadUrl; | ||
| }); | ||
| } | ||
| } | ||
| exports.AzModuleInstaller = AzModuleInstaller; | ||
This file contains hidden or 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,56 @@ | ||
| "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 __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const exec_1 = require("@actions/exec"); | ||
| const io_1 = require("@actions/io"); | ||
| const PowerShellToolRunner_1 = __importDefault(require("./PowerShellToolRunner")); | ||
| class ArchiveTools { | ||
| constructor(use7Zip = false) { | ||
| this.use7Zip = use7Zip; | ||
| } | ||
| unzip(zipPath, destination) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| if (this.use7Zip) { | ||
| yield this.unzipUsing7Zip(zipPath, destination); | ||
| } | ||
| else { | ||
| yield this.unzipUsingPowerShell(zipPath, destination); | ||
| } | ||
| }); | ||
| } | ||
| unzipUsing7Zip(zipPath, destination) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| const path7Zip = yield io_1.which("7z.exe", true); | ||
| const exitCode = yield exec_1.exec(`${path7Zip} x -o${destination} ${zipPath}`); | ||
| if (exitCode != 0) { | ||
| throw new Error(`Extraction using 7zip failed from ${zipPath} to ${destination}`); | ||
| } | ||
| }); | ||
| } | ||
| unzipUsingPowerShell(zipPath, destination) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| const script = ` | ||
| $prevProgressPref = $ProgressPreference | ||
| $ProgressPreference = 'SilentlyContinue' | ||
| Expand-Archive -Path ${zipPath} -DestinationPath ${destination} | ||
| $ProgressPreference = $prevProgressPref`; | ||
| PowerShellToolRunner_1.default.init(); | ||
| const exitCode = yield PowerShellToolRunner_1.default.executePowerShellScriptBlock(script); | ||
| if (exitCode != 0) { | ||
| throw new Error(`Extraction using Expand-Archive cmdlet failed from ${zipPath} to ${destination}`); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| exports.ArchiveTools = ArchiveTools; |
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.