From 0ea540940ee276d96c1b1aaed5e1118aaabdcec2 Mon Sep 17 00:00:00 2001 From: Robin Raju Date: Mon, 20 Jun 2022 11:40:24 +0200 Subject: [PATCH] Configurable api url to add support for github enterprise server (#464) * Add github-api-url to workflow input * Update readme --- README.md | 5 ++++ __tests__/main.test.ts | 29 +++++++++++++++++++- __tests__/resource/2-gh-enterprise.json | 36 +++++++++++++++++++++++++ action.yml | 4 +++ dist/index.js | 11 ++++---- src/main.ts | 3 ++- src/release-downloader.ts | 9 ++++--- 7 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 __tests__/resource/2-gh-enterprise.json diff --git a/README.md b/README.md index a000bee..eebb656 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,11 @@ A Github Action to download assets from github release. It can download specifie # https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets # eg: token: ${{ secrets.MY_TOKEN }} token: "" + + # The URL of the Github API, only use this input if you are using Github Enterprise + # Default: "https://api.github.com" + # Use http(s)://[hostname]/api/v3 to access the API for GitHub Enterprise Server + github-api-url: "" ``` ## Scenarios diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts index 2ed7e07..b4b4bc2 100644 --- a/__tests__/main.test.ts +++ b/__tests__/main.test.ts @@ -14,13 +14,14 @@ const outputFilePath = "./test-output" beforeEach(() => { const githubtoken = process.env.REPO_TOKEN || "" + const githubApiUrl = "https://api.github.com" const credentialHandler = new handlers.BearerCredentialHandler( githubtoken, false ) httpClent = new thc.HttpClient("gh-api-client", [credentialHandler]) - downloader = new ReleaseDownloader(httpClent) + downloader = new ReleaseDownloader(httpClent, githubApiUrl) nock("https://api.github.com") .get("/repos/robinraju/probable-potato/releases/latest") @@ -61,6 +62,16 @@ beforeEach(() => { }) .get("/repos/robinraju/probable-potato/releases/assets/66946551") .replyWithFile(200, __dirname + "/resource/assets/file_example.csv") + + nock("https://my-gh-host.com/api/v3") + .get("/repos/my-enterprise/test-repo/releases/latest") + .reply(200, readFromFile("2-gh-enterprise.json")) + + nock("https://my-gh-host.com/api/v3", { + reqheaders: {accept: "application/octet-stream"} + }) + .get("/repos/my-enterprise/test-repo/releases/assets/66946546") + .replyWithFile(200, __dirname + "/resource/assets/test-1.txt") }) afterEach(async () => { @@ -156,3 +167,19 @@ test("Download a csv file with wildcard filename", async () => { const result = await downloader.download(downloadSettings) expect(result.length).toBe(1) }, 10000) + +test("Download file from Github Enterprise server", async () => { + downloader = new ReleaseDownloader(httpClent, "https://my-gh-host.com/api/v3") + + const downloadSettings: IReleaseDownloadSettings = { + sourceRepoPath: "my-enterprise/test-repo", + isLatest: true, + tag: "", + fileName: "test-1.txt", + tarBall: false, + zipBall: false, + outFilePath: outputFilePath + } + const result = await downloader.download(downloadSettings) + expect(result.length).toBe(1) +}, 10000) diff --git a/__tests__/resource/2-gh-enterprise.json b/__tests__/resource/2-gh-enterprise.json new file mode 100644 index 0000000..4d3e3a7 --- /dev/null +++ b/__tests__/resource/2-gh-enterprise.json @@ -0,0 +1,36 @@ +{ + "url": "https://my-gh-host.com/api/v3/repos/my-enterprise/test-repo/releases/68092191", + "assets_url": "https://my-gh-host.com/api/v3/repos/my-enterprise/test-repo/releases/68092191/assets", + "upload_url": "https://my-gh-host.com/api/v3/repos/my-enterprise/test-repo/releases/68092191/assets{?name,label}", + "html_url": "https://my-gh-host.com/repos/my-enterprise/test-repo/releases/tag/1.0.1", + "id": 68092191, + "author": {}, + "node_id": "RE_kwDOHahpL84EDwEf", + "tag_name": "1.0.1", + "target_commitish": "main", + "name": "v1.0.1", + "draft": false, + "prerelease": false, + "created_at": "2022-05-29T12:03:47Z", + "published_at": "2022-05-29T12:04:42Z", + "assets": [ + { + "url": "https://my-gh-host.com/api/v3/repos/my-enterprise/test-repo/releases/assets/66946546", + "id": 66946546, + "node_id": "RA_kwDOHahpL84D_YXy", + "name": "test-1.txt", + "label": null, + "uploader": {}, + "content_type": "text/plain", + "state": "uploaded", + "size": 7253, + "download_count": 56, + "created_at": "2022-05-29T12:08:23Z", + "updated_at": "2022-05-29T12:08:23Z", + "browser_download_url": "https://my-gh-host.com/api/v3/repos/my-enterprise/test-repo/releases/download/1.0.1/test-1.txt" + } + ], + "tarball_url": "https://my-gh-host.com/api/v3/repos/my-enterprise/test-repo/tarball/1.0.1", + "zipball_url": "https://my-gh-host.com/api/v3/repos/my-enterprise/test-repo/zipball/1.0.1", + "body": "" +} \ No newline at end of file diff --git a/action.yml b/action.yml index c83f976..2db9336 100644 --- a/action.yml +++ b/action.yml @@ -34,6 +34,10 @@ inputs: description: "Github token to access private repos" default: ${{ github.token }} required: false + github-api-url: + description: "The URL of the Github API, only use this input if you are using Github Enterprise" + default: "https://api.github.com" + required: false runs: using: "node16" main: "dist/index.js" diff --git a/dist/index.js b/dist/index.js index 08e855f..f32d9ab 100644 --- a/dist/index.js +++ b/dist/index.js @@ -113,11 +113,12 @@ function run() { try { const downloadSettings = inputHelper.getInputs(); const authToken = core.getInput("token"); + const githubApiUrl = core.getInput("github-api-url"); const credentialHandler = new handlers.BearerCredentialHandler(authToken, false); const httpClient = new thc.HttpClient("gh-api-client", [ credentialHandler ]); - const downloader = new release_downloader_1.ReleaseDownloader(httpClient); + const downloader = new release_downloader_1.ReleaseDownloader(httpClient, githubApiUrl); const res = yield downloader.download(downloadSettings); core.info(`Done: ${res}`); } @@ -177,9 +178,9 @@ const fs = __importStar(__nccwpck_require__(7147)); const io = __importStar(__nccwpck_require__(7436)); const path = __importStar(__nccwpck_require__(1017)); class ReleaseDownloader { - constructor(httpClient) { - this._apiRoot = "https://api.github.com/repos"; + constructor(httpClient, githubApiUrl) { this.httpClient = httpClient; + this.apiRoot = githubApiUrl; } download(downloadSettings) { return __awaiter(this, void 0, void 0, function* () { @@ -202,7 +203,7 @@ class ReleaseDownloader { return __awaiter(this, void 0, void 0, function* () { core.info(`Fetching latest release for repo ${repoPath}`); const headers = { Accept: "application/vnd.github.v3+json" }; - const response = yield this.httpClient.get(`${this._apiRoot}/${repoPath}/releases/latest`, headers); + const response = yield this.httpClient.get(`${this.apiRoot}/repos/${repoPath}/releases/latest`, headers); if (response.message.statusCode !== 200) { const err = new Error(`[getlatestRelease] Unexpected response: ${response.message.statusCode}`); throw err; @@ -225,7 +226,7 @@ class ReleaseDownloader { throw new Error("Config error: Please input a valid tag"); } const headers = { Accept: "application/vnd.github.v3+json" }; - const response = yield this.httpClient.get(`${this._apiRoot}/${repoPath}/releases/tags/${tag}`, headers); + const response = yield this.httpClient.get(`${this.apiRoot}/repos/${repoPath}/releases/tags/${tag}`, headers); if (response.message.statusCode !== 200) { const err = new Error(`[getReleaseByTag] Unexpected response: ${response.message.statusCode}`); throw err; diff --git a/src/main.ts b/src/main.ts index 69494ee..282f041 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,6 +9,7 @@ async function run(): Promise { try { const downloadSettings = inputHelper.getInputs() const authToken = core.getInput("token") + const githubApiUrl = core.getInput("github-api-url") const credentialHandler = new handlers.BearerCredentialHandler( authToken, @@ -18,7 +19,7 @@ async function run(): Promise { credentialHandler ]) - const downloader = new ReleaseDownloader(httpClient) + const downloader = new ReleaseDownloader(httpClient, githubApiUrl) const res: string[] = await downloader.download(downloadSettings) core.info(`Done: ${res}`) diff --git a/src/release-downloader.ts b/src/release-downloader.ts index f08c3f6..7410742 100644 --- a/src/release-downloader.ts +++ b/src/release-downloader.ts @@ -12,10 +12,11 @@ import {IReleaseDownloadSettings} from "./download-settings" export class ReleaseDownloader { private httpClient: thc.HttpClient - private _apiRoot = "https://api.github.com/repos" + private apiRoot: string - constructor(httpClient: thc.HttpClient) { + constructor(httpClient: thc.HttpClient, githubApiUrl: string) { this.httpClient = httpClient + this.apiRoot = githubApiUrl } async download( @@ -53,7 +54,7 @@ export class ReleaseDownloader { const headers: IHeaders = {Accept: "application/vnd.github.v3+json"} const response = await this.httpClient.get( - `${this._apiRoot}/${repoPath}/releases/latest`, + `${this.apiRoot}/repos/${repoPath}/releases/latest`, headers ) @@ -89,7 +90,7 @@ export class ReleaseDownloader { const headers: IHeaders = {Accept: "application/vnd.github.v3+json"} const response = await this.httpClient.get( - `${this._apiRoot}/${repoPath}/releases/tags/${tag}`, + `${this.apiRoot}/repos/${repoPath}/releases/tags/${tag}`, headers )