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  }