github.com/jfrog/frogbot@v1.1.1-0.20231221090046-821a26f50338/action/src/utils.ts (about) 1 import * as core from '@actions/core'; 2 import { exec } from '@actions/exec'; 3 import { context as githubContext } from '@actions/github'; 4 import { downloadTool, find, cacheFile } from '@actions/tool-cache'; 5 import { chmodSync } from 'fs'; 6 import { platform, arch } from 'os'; 7 import { normalize, join } from 'path'; 8 import { BranchSummary, SimpleGit, simpleGit } from 'simple-git'; 9 10 export class Utils { 11 private static readonly LATEST_RELEASE_VERSION: string = '[RELEASE]'; 12 private static readonly LATEST_CLI_VERSION_ARG: string = 'latest'; 13 private static readonly VERSION_ARG: string = 'version'; 14 private static readonly TOOL_NAME: string = 'frogbot'; 15 16 public static async addToPath() { 17 let fileName: string = Utils.getExecutableName(); 18 let version: string = core.getInput(Utils.VERSION_ARG); 19 let major: string = version.split('.')[0]; 20 if (version === this.LATEST_CLI_VERSION_ARG) { 21 version = Utils.LATEST_RELEASE_VERSION; 22 major = '2'; 23 } else { 24 if (this.loadFromCache(version)) { 25 // Download is not needed 26 return; 27 } 28 } 29 30 // Download Frogbot 31 const releasesRepo: string = process.env.JF_RELEASES_REPO ?? ''; 32 let url: string = Utils.getCliUrl(major, version, fileName, releasesRepo); 33 core.debug('Downloading Frogbot from ' + url); 34 let auth: string = this.generateAuthString(releasesRepo); 35 let downloadDir: string = await downloadTool(url, '', auth); 36 // Cache 'frogbot' executable 37 await this.cacheAndAddPath(downloadDir, version, fileName); 38 } 39 40 public static generateAuthString(releasesRepo: string): string { 41 if (!releasesRepo) { 42 return ''; 43 } 44 let accessToken: string = process.env.JF_ACCESS_TOKEN ?? ''; 45 let username: string = process.env.JF_USER ?? ''; 46 let password: string = process.env.JF_PASSWORD ?? ''; 47 if (accessToken) { 48 return 'Bearer ' + Buffer.from(accessToken).toString(); 49 } else if (username && password) { 50 return 'Basic ' + Buffer.from(username + ':' + password).toString('base64'); 51 } 52 return ''; 53 } 54 55 public static async setFrogbotEnv() { 56 core.exportVariable('JF_GIT_PROVIDER', 'github'); 57 core.exportVariable('JF_GIT_OWNER', githubContext.repo.owner); 58 let owner: string | undefined = githubContext.repo.repo; 59 if (owner) { 60 core.exportVariable('JF_GIT_REPO', owner.substring(owner.indexOf('/') + 1)); 61 } 62 core.exportVariable('JF_GIT_PULL_REQUEST_ID', githubContext.issue.number); 63 return githubContext.eventName; 64 } 65 66 /** 67 * Execute frogbot scan-pull-request command. 68 */ 69 public static async execScanPullRequest() { 70 if (!process.env.JF_GIT_BASE_BRANCH) { 71 core.exportVariable('JF_GIT_BASE_BRANCH', githubContext.ref); 72 } 73 let res: number = await exec(Utils.getExecutableName(), ['scan-pull-request']); 74 if (res !== core.ExitCode.Success) { 75 throw new Error('Frogbot exited with exit code ' + res); 76 } 77 } 78 79 /** 80 * Execute frogbot scan-repository command. 81 */ 82 public static async execCreateFixPullRequests() { 83 if (!process.env.JF_GIT_BASE_BRANCH) { 84 // Get the current branch we are checked on 85 const git: SimpleGit = simpleGit(); 86 try { 87 const currentBranch: BranchSummary = await git.branch(); 88 core.exportVariable('JF_GIT_BASE_BRANCH', currentBranch.current); 89 } catch (error) { 90 throw new Error('Error getting current branch from the .git folder: ' + error); 91 } 92 } 93 94 let res: number = await exec(Utils.getExecutableName(), ['scan-repository']); 95 if (res !== core.ExitCode.Success) { 96 throw new Error('Frogbot exited with exit code ' + res); 97 } 98 } 99 100 /** 101 * Try to load the Frogbot executables from cache. 102 * 103 * @param version - Frogbot version 104 * @returns true if the CLI executable was loaded from cache and added to path 105 */ 106 private static loadFromCache(version: string): boolean { 107 let execPath: string = find(Utils.TOOL_NAME, version); 108 if (execPath) { 109 core.addPath(execPath); 110 return true; 111 } 112 return false; 113 } 114 115 /** 116 * Add Frogbot executable to cache and to the system path. 117 * @param downloadDir - The directory whereby the CLI was downloaded to 118 * @param version - Frogbot version 119 * @param fileName - 'frogbot' or 'frogbot.exe' 120 */ 121 private static async cacheAndAddPath(downloadDir: string, version: string, fileName: string) { 122 let cliDir: string = await cacheFile(downloadDir, fileName, Utils.TOOL_NAME, version); 123 if (!Utils.isWindows()) { 124 let filePath: string = normalize(join(cliDir, fileName)); 125 chmodSync(filePath, 0o555); 126 } 127 core.addPath(cliDir); 128 } 129 130 public static getCliUrl(major: string, version: string, fileName: string, releasesRepo: string): string { 131 let architecture: string = 'frogbot-' + Utils.getArchitecture(); 132 if (releasesRepo) { 133 let platformUrl: string = process.env.JF_URL ?? ''; 134 if (!platformUrl) { 135 throw new Error('Failed while downloading Frogbot from Artifactory, JF_URL must be set'); 136 } 137 // Remove trailing slash if exists 138 platformUrl = platformUrl.replace(/\/$/, ''); 139 return `${platformUrl}/artifactory/${releasesRepo}/artifactory/frogbot/v${major}/${version}/${architecture}/${fileName}`; 140 } 141 return `https://releases.jfrog.io/artifactory/frogbot/v${major}/${version}/${architecture}/${fileName}`; 142 } 143 144 public static getArchitecture() { 145 if (Utils.isWindows()) { 146 return 'windows-amd64'; 147 } 148 if (platform().includes('darwin')) { 149 return 'mac-386'; 150 } 151 if (arch().includes('arm')) { 152 return arch().includes('64') ? 'linux-arm64' : 'linux-arm'; 153 } 154 if (arch().includes('ppc64le')) { 155 return 'linux-ppc64le'; 156 } 157 if (arch().includes('ppc64')) { 158 return 'linux-ppc64'; 159 } 160 return arch().includes('64') ? 'linux-amd64' : 'linux-386'; 161 } 162 163 public static getExecutableName() { 164 return Utils.isWindows() ? 'frogbot.exe' : 'frogbot'; 165 } 166 167 public static isWindows() { 168 return platform().startsWith('win'); 169 } 170 }