diff --git a/action/lib/utils.js b/action/lib/utils.js index 6686eab76..6d3b61fc6 100644 --- a/action/lib/utils.js +++ b/action/lib/utils.js @@ -42,6 +42,7 @@ const os = __importStar(require("os")); const path = __importStar(require("path")); class Utils { static addToPath() { + var _a; return __awaiter(this, void 0, void 0, function* () { let fileName = Utils.getExecutableName(); let version = core.getInput(Utils.VERSION_ARG); @@ -57,13 +58,31 @@ class Utils { } } // Download Frogbot - let url = Utils.getCliUrl(major, version, fileName); + const releasesRepo = (_a = process.env.JF_RELEASES_REPO) !== null && _a !== void 0 ? _a : ''; + let url = Utils.getCliUrl(major, version, fileName, releasesRepo); core.debug('Downloading Frogbot from ' + url); - let downloadDir = yield toolCache.downloadTool(url); + let auth = this.generateAuthString(releasesRepo); + let downloadDir = yield toolCache.downloadTool(url, '', auth); // Cache 'frogbot' executable yield this.cacheAndAddPath(downloadDir, version, fileName); }); } + static generateAuthString(releasesRepo) { + var _a, _b, _c; + if (!releasesRepo) { + return ''; + } + let accessToken = (_a = process.env.JF_ACCESS_TOKEN) !== null && _a !== void 0 ? _a : ''; + let username = (_b = process.env.JF_USER) !== null && _b !== void 0 ? _b : ''; + let password = (_c = process.env.JF_PASSWORD) !== null && _c !== void 0 ? _c : ''; + if (accessToken) { + return 'Bearer ' + Buffer.from(accessToken).toString(); + } + else if (username && password) { + return 'Basic ' + Buffer.from(username + ':' + password).toString('base64'); + } + return ''; + } static setFrogbotEnv() { core.exportVariable('JF_GIT_PROVIDER', 'github'); core.exportVariable('JF_GIT_OWNER', github.context.repo.owner); @@ -126,8 +145,18 @@ class Utils { core.addPath(cliDir); }); } - static getCliUrl(major, version, fileName) { + static getCliUrl(major, version, fileName, releasesRepo) { + var _a; let architecture = 'frogbot-' + Utils.getArchitecture(); + if (releasesRepo) { + let platformUrl = (_a = process.env.JF_URL) !== null && _a !== void 0 ? _a : ''; + if (!platformUrl) { + throw new Error('Failed while downloading Frogbot from Artifactory, JF_URL must be set'); + } + // Remove trailing slash if exists + platformUrl = platformUrl.replace(/\/$/, ''); + return `${platformUrl}/artifactory/${releasesRepo}/artifactory/frogbot/v${major}/${version}/${architecture}/${fileName}`; + } return `https://releases.jfrog.io/artifactory/frogbot/v${major}/${version}/${architecture}/${fileName}`; } static getArchitecture() { diff --git a/action/package-lock.json b/action/package-lock.json index 77ae3553b..64fa7e44b 100644 --- a/action/package-lock.json +++ b/action/package-lock.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@types/jest": "^27.5.0", - "@types/node": "^18.0.3", + "@types/node": "^18.16.18", "@typescript-eslint/eslint-plugin": "^5.15.0", "@typescript-eslint/parser": "^5.15.0", "eslint": "^8.11.0", @@ -1441,9 +1441,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.7.tgz", - "integrity": "sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ==", + "version": "18.16.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.18.tgz", + "integrity": "sha512-/aNaQZD0+iSBAGnvvN2Cx92HqE5sZCPZtx2TsK+4nvV23fFe09jVDvpArXr2j9DnYlzuU9WuoykDDc6wqvpNcw==", "dev": true }, "node_modules/@types/prettier": { @@ -6581,9 +6581,9 @@ "dev": true }, "@types/node": { - "version": "18.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.7.tgz", - "integrity": "sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ==", + "version": "18.16.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.18.tgz", + "integrity": "sha512-/aNaQZD0+iSBAGnvvN2Cx92HqE5sZCPZtx2TsK+4nvV23fFe09jVDvpArXr2j9DnYlzuU9WuoykDDc6wqvpNcw==", "dev": true }, "@types/prettier": { diff --git a/action/package.json b/action/package.json index 2510abbda..340f0ea52 100644 --- a/action/package.json +++ b/action/package.json @@ -43,7 +43,7 @@ }, "devDependencies": { "@types/jest": "^27.5.0", - "@types/node": "^18.0.3", + "@types/node": "^18.16.18", "@typescript-eslint/eslint-plugin": "^5.15.0", "@typescript-eslint/parser": "^5.15.0", "eslint": "^8.11.0", diff --git a/action/src/utils.ts b/action/src/utils.ts index 98367df14..bdc6485fe 100644 --- a/action/src/utils.ts +++ b/action/src/utils.ts @@ -27,14 +27,30 @@ export class Utils { } // Download Frogbot - let url: string = Utils.getCliUrl(major, version, fileName); + const releasesRepo: string = process.env.JF_RELEASES_REPO ?? ''; + let url: string = Utils.getCliUrl(major, version, fileName, releasesRepo); core.debug('Downloading Frogbot from ' + url); - let downloadDir: string = await toolCache.downloadTool(url); - + let auth: string = this.generateAuthString(releasesRepo); + let downloadDir: string = await toolCache.downloadTool(url, '', auth); // Cache 'frogbot' executable await this.cacheAndAddPath(downloadDir, version, fileName); } + public static generateAuthString(releasesRepo: string): string { + if (!releasesRepo) { + return '' + } + let accessToken: string = process.env.JF_ACCESS_TOKEN ?? ''; + let username: string = process.env.JF_USER ?? ''; + let password: string = process.env.JF_PASSWORD ?? ''; + if (accessToken) { + return 'Bearer ' + Buffer.from(accessToken).toString(); + } else if (username && password) { + return 'Basic ' + Buffer.from(username + ':' + password).toString('base64'); + } + return ''; + } + public static setFrogbotEnv() { core.exportVariable('JF_GIT_PROVIDER', 'github'); core.exportVariable('JF_GIT_OWNER', github.context.repo.owner); @@ -96,8 +112,17 @@ export class Utils { core.addPath(cliDir); } - public static getCliUrl(major: string, version: string, fileName: string): string { + public static getCliUrl(major: string, version: string, fileName: string, releasesRepo: string): string { let architecture: string = 'frogbot-' + Utils.getArchitecture(); + if (releasesRepo) { + let platformUrl: string = process.env.JF_URL ?? ''; + if (!platformUrl) { + throw new Error('Failed while downloading Frogbot from Artifactory, JF_URL must be set'); + } + // Remove trailing slash if exists + platformUrl = platformUrl.replace(/\/$/, ''); + return `${platformUrl}/artifactory/${releasesRepo}/artifactory/frogbot/v${major}/${version}/${architecture}/${fileName}`; + } return `https://releases.jfrog.io/artifactory/frogbot/v${major}/${version}/${architecture}/${fileName}`; } diff --git a/action/test/main.spec.ts b/action/test/main.spec.ts index 8e04a4569..9ccf25512 100644 --- a/action/test/main.spec.ts +++ b/action/test/main.spec.ts @@ -4,6 +4,16 @@ import { Utils } from '../src/utils'; jest.mock('os'); describe('Frogbot Action Tests', () => { + afterEach(() => { + delete process.env.JF_ACCESS_TOKEN; + delete process.env.JF_USER; + delete process.env.PASSWORD; + delete process.env.JF_GIT_PROVIDER; + delete process.env.JF_GIT_OWNER; + delete process.env.GITHUB_REPOSITORY_OWNER; + delete process.env.GITHUB_REPOSITORY; + }) + describe('Frogbot URL Tests', () => { const myOs: jest.Mocked = os as any; let cases: string[][] = [ @@ -25,11 +35,65 @@ describe('Frogbot Action Tests', () => { test.each(cases)('CLI Url for %s-%s', (platform, arch, fileName, expectedUrl) => { myOs.platform.mockImplementation(() => platform); myOs.arch.mockImplementation(() => arch); - let cliUrl: string = Utils.getCliUrl('1', '1.2.3', fileName); + let cliUrl: string = Utils.getCliUrl('1', '1.2.3', fileName, ''); expect(cliUrl).toBe(expectedUrl); }); }); + describe('Frogbot URL Tests With Remote Artifactory', () => { + const myOs: jest.Mocked = os as any; + const releasesRepo: string = 'frogbot-remote'; + process.env['JF_URL'] = 'https://myfrogbot.com/'; + process.env['JF_ACCESS_TOKEN'] = 'access_token1'; + let cases: string[][] = [ + [ + 'win32' as NodeJS.Platform, + 'amd64', + 'jfrog.exe', + 'https://myfrogbot.com/artifactory/frogbot-remote/artifactory/frogbot/v2/2.8.7/frogbot-windows-amd64/jfrog.exe', + ], + ['darwin' as NodeJS.Platform, 'amd64', 'jfrog', 'https://myfrogbot.com/artifactory/frogbot-remote/artifactory/frogbot/v2/2.8.7/frogbot-mac-386/jfrog'], + ['linux' as NodeJS.Platform, 'amd64', 'jfrog', 'https://myfrogbot.com/artifactory/frogbot-remote/artifactory/frogbot/v2/2.8.7/frogbot-linux-amd64/jfrog'], + ['linux' as NodeJS.Platform, 'arm64', 'jfrog', 'https://myfrogbot.com/artifactory/frogbot-remote/artifactory/frogbot/v2/2.8.7/frogbot-linux-arm64/jfrog'], + ['linux' as NodeJS.Platform, '386', 'jfrog', 'https://myfrogbot.com/artifactory/frogbot-remote/artifactory/frogbot/v2/2.8.7/frogbot-linux-386/jfrog'], + ['linux' as NodeJS.Platform, 'arm', 'jfrog', 'https://myfrogbot.com/artifactory/frogbot-remote/artifactory/frogbot/v2/2.8.7/frogbot-linux-arm/jfrog'], + ['linux' as NodeJS.Platform, 'ppc64', 'jfrog', 'https://myfrogbot.com/artifactory/frogbot-remote/artifactory/frogbot/v2/2.8.7/frogbot-linux-ppc64/jfrog'], + ['linux' as NodeJS.Platform, 'ppc64le', 'jfrog', 'https://myfrogbot.com/artifactory/frogbot-remote/artifactory/frogbot/v2/2.8.7/frogbot-linux-ppc64le/jfrog'], + ]; + + test.each(cases)('Remote CLI Url for %s-%s', (platform, arch, fileName, expectedUrl) => { + myOs.platform.mockImplementation(() => platform); + myOs.arch.mockImplementation(() => arch); + let cliUrl: string = Utils.getCliUrl('2', '2.8.7', fileName, releasesRepo); + expect(cliUrl).toBe(expectedUrl); + }); + }); + + describe('Generate auth string', () => { + it('Should return an empty string if releasesRepo is falsy', () => { + const result = Utils.generateAuthString(''); + expect(result).toBe(''); + }); + + it('Should generate a Bearer token if accessToken is provided', () => { + process.env.JF_ACCESS_TOKEN = 'yourAccessToken'; + const result = Utils.generateAuthString('yourReleasesRepo'); + expect(result).toBe('Bearer yourAccessToken'); + }); + + it('Should generate a Basic token if username and password are provided', () => { + process.env.JF_USER = 'yourUsername'; + process.env.JF_PASSWORD = 'yourPassword'; + const result = Utils.generateAuthString('yourReleasesRepo'); + expect(result).toBe('Basic eW91clVzZXJuYW1lOnlvdXJQYXNzd29yZA=='); + }); + + it('Should return an empty string if no credentials are provided', () => { + const result = Utils.generateAuthString('yourReleasesRepo'); + expect(result).toBe(''); + }); + }); + it('Repository env tests', () => { process.env['GITHUB_REPOSITORY_OWNER'] = 'jfrog'; process.env['GITHUB_REPOSITORY'] = 'jfrog/frogbot';