diff --git a/__tests__/cakeRelease.test.ts b/__tests__/cakeRelease.test.ts new file mode 100644 index 0000000..b189670 --- /dev/null +++ b/__tests__/cakeRelease.test.ts @@ -0,0 +1,112 @@ +import * as http from '@actions/http-client'; +import * as cakeRelease from '../src/cakeRelease'; + +describe('When retrieving the latest Cake version', () => { + beforeAll(async () => { + jest + .spyOn(http.HttpClient.prototype, 'getJson') + .mockImplementation(async () => ({ + statusCode: 200, + result: { + tag_name: 'v1.0.0' + }, + headers: {} + })); + }); + + test('it should return the latest version number from GitHub', async () => { + expect(await cakeRelease.getLatestVersion()).toBe('1.0.0'); + }); +}); + +describe('When retrieving the latest Cake version without the \'v\' prefix', () => { + beforeAll(async () => { + jest + .spyOn(http.HttpClient.prototype, 'getJson') + .mockImplementation(async () => ({ + statusCode: 200, + result: { + tag_name: '1.0.0' + }, + headers: {} + })); + }); + + test('it should return the latest version number from GitHub', async () => { + expect(await cakeRelease.getLatestVersion()).toBe('1.0.0'); + }); +}); + +describe('When failing to retrieve the latest Cake version due to a GitHub error', () => { + beforeAll(async () => { + jest + .spyOn(http.HttpClient.prototype, 'getJson') + .mockImplementation(async () => ({ + statusCode: 500, + result: {}, + headers: {} + })); + }); + + test('it should return null', async () => { + expect(await cakeRelease.getLatestVersion()).toBeNull(); + }); + + test('it should log the fact that the GitHub API returned an error', async () => { + const log = jest.spyOn(console, 'log'); + await cakeRelease.getLatestVersion(); + expect(log).toHaveBeenCalledWith('Could not determine the latest version of Cake. GitHub returned status code 500'); + }); +}); + +describe('When failing to retrieve the latest Cake version due to an empty response from GitHub', () => { + beforeAll(async () => { + jest + .spyOn(http.HttpClient.prototype, 'getJson') + .mockImplementation(async () => ({ + statusCode: 200, + result: {}, + headers: {} + })); + }); + + test('it should return null', async () => { + expect(await cakeRelease.getLatestVersion()).toBeNull(); + }); +}); + +describe('When failing to retrieve the latest Cake version due to a missing tag name in the GitHub response', () => { + beforeAll(async () => { + jest + .spyOn(http.HttpClient.prototype, 'getJson') + .mockImplementation(async () => ({ + statusCode: 200, + result: { + tag_name: null + }, + headers: {} + })); + }); + + test('it should return null', async () => { + expect(await cakeRelease.getLatestVersion()).toBeNull(); + }); +}); + +describe('When failing to retrieve the latest Cake version due to an empty tag name in the GitHub response', () => { + beforeAll(async () => { + jest + .spyOn(http.HttpClient.prototype, 'getJson') + .mockImplementation(async () => ({ + statusCode: 200, + result: { + tag_name: '' + }, + headers: {} + })); + }); + + test('it should return null', async () => { + expect(await cakeRelease.getLatestVersion()).toBeNull(); + }); +}); diff --git a/package-lock.json b/package-lock.json index 2aca2bb..9c12edd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@actions/core": "^1.9.1", "@actions/exec": "^1.0.1", + "@actions/http-client": "^2.0.1", "@actions/io": "^1.0.1" }, "devDependencies": { diff --git a/package.json b/package.json index 9f28b32..cf59eb7 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "dependencies": { "@actions/core": "^1.9.1", "@actions/exec": "^1.0.1", + "@actions/http-client": "^2.0.1", "@actions/io": "^1.0.1" }, "devDependencies": { diff --git a/src/cakeRelease.ts b/src/cakeRelease.ts new file mode 100644 index 0000000..cf240e2 --- /dev/null +++ b/src/cakeRelease.ts @@ -0,0 +1,26 @@ +import * as http from '@actions/http-client'; + +export async function getLatestVersion(): Promise { + const release = await getLatestCakeReleaseFromGitHub(); + return extractVersionNumber(release); +} + +async function getLatestCakeReleaseFromGitHub(): Promise { + const client = new http.HttpClient('cake-build/cake-action'); + const response = await client.getJson('https://api.github.com/repos/cake-build/cake/releases/latest'); + + if (response.statusCode != 200) { + console.log(`Could not determine the latest version of Cake. GitHub returned status code ${response.statusCode}`); + return null; + } + + return response.result; +} + +function extractVersionNumber(release: GitHubRelease | null): string | null { + return release?.tag_name?.replace(/^v/, '') || null; +} + +interface GitHubRelease { + tag_name: string; +}