Skip to content

Commit 623a3e0

Browse files
authored
Add support to extract release archives - fixes #612 (#613)
* support automatic extraction of archives * bump actions/io to 1.1.2 & update dev deps * add extractAssets to interface & fix input parsing * Update download-settings: fix doc comment
1 parent 36198f7 commit 623a3e0

13 files changed

+34296
-11649
lines changed

README.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@ A Github Action to download assets from github release. It can download specifie
4141
# It will create the target directory automatically if not present
4242
# eg: out-file-path: "my-downloads" => It will create directory $GITHUB_WORKSPACE/my-downloads
4343
out-file-path: ""
44-
44+
45+
# A flag to set if the downloaded assets are archives and should be extracted
46+
# Checks all downloaded files if they end with zip, tar or tar.gz and extracts them, if true.
47+
# Prints a warning if enabled but file is not an archive - but does not fail.
48+
extract: false
49+
4550
# Github access token to download files from private repositories
4651
# https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets
4752
# eg: token: ${{ secrets.MY_TOKEN }}
@@ -138,3 +143,13 @@ A Github Action to download assets from github release. It can download specifie
138143
releaseId: "123123"
139144
fileName: "foo.zip"
140145
```
146+
147+
### Download and extracts archives
148+
149+
```yaml
150+
- uses: robinraju/[email protected]
151+
with:
152+
fileName: "foo.zip"
153+
latest: true
154+
extract: true
155+
```

__tests__/main.test.ts

+44-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import * as core from "@actions/core"
22
import * as fs from "fs"
3+
import * as path from "path"
34
import * as handlers from "typed-rest-client/Handlers"
45
import * as io from "@actions/io"
56
import * as thc from "typed-rest-client/HttpClient"
67

78
import {IReleaseDownloadSettings} from "../src/download-settings"
89
import {ReleaseDownloader} from "../src/release-downloader"
910
import nock from "nock"
11+
import {extract} from "../src/unarchive"
1012

1113
let downloader: ReleaseDownloader
1214
let httpClent: thc.HttpClient
@@ -61,6 +63,12 @@ beforeEach(() => {
6163
.get("/repos/robinraju/probable-potato/releases/assets/66946550")
6264
.replyWithFile(200, __dirname + "/resource/assets/lorem-ipsum.pdf")
6365

66+
nock("https://api.github.com", {
67+
reqheaders: {accept: "application/octet-stream"}
68+
})
69+
.get("/repos/robinraju/probable-potato/releases/assets/66946552")
70+
.replyWithFile(200, __dirname + "/resource/assets/archive-example.zip")
71+
6472
nock("https://api.github.com", {
6573
reqheaders: {accept: "application/octet-stream"}
6674
})
@@ -97,10 +105,11 @@ test("Download all files from public repo", async () => {
97105
fileName: "*",
98106
tarBall: false,
99107
zipBall: false,
108+
extractAssets: false,
100109
outFilePath: outputFilePath
101110
}
102111
const result = await downloader.download(downloadSettings)
103-
expect(result.length).toBe(6)
112+
expect(result.length).toBe(7)
104113
}, 10000)
105114

106115
test("Download single file from public repo", async () => {
@@ -112,6 +121,7 @@ test("Download single file from public repo", async () => {
112121
fileName: "test-1.txt",
113122
tarBall: false,
114123
zipBall: false,
124+
extractAssets: false,
115125
outFilePath: outputFilePath
116126
}
117127
const result = await downloader.download(downloadSettings)
@@ -127,6 +137,7 @@ test("Fail loudly if given filename is not found in a release", async () => {
127137
fileName: "missing-file.txt",
128138
tarBall: false,
129139
zipBall: false,
140+
extractAssets: false,
130141
outFilePath: outputFilePath
131142
}
132143
const result = downloader.download(downloadSettings)
@@ -144,6 +155,7 @@ test("Fail loudly if release is not identified", async () => {
144155
fileName: "missing-file.txt",
145156
tarBall: false,
146157
zipBall: false,
158+
extractAssets: false,
147159
outFilePath: outputFilePath
148160
}
149161
const result = downloader.download(downloadSettings)
@@ -161,6 +173,7 @@ test("Download files with wildcard from public repo", async () => {
161173
fileName: "test-*.txt",
162174
tarBall: false,
163175
zipBall: false,
176+
extractAssets: false,
164177
outFilePath: outputFilePath
165178
}
166179
const result = await downloader.download(downloadSettings)
@@ -176,6 +189,7 @@ test("Download single file with wildcard from public repo", async () => {
176189
fileName: "3-*.txt",
177190
tarBall: false,
178191
zipBall: false,
192+
extractAssets: false,
179193
outFilePath: outputFilePath
180194
}
181195
const result = await downloader.download(downloadSettings)
@@ -191,6 +205,7 @@ test("Download multiple pdf files with wildcard filename", async () => {
191205
fileName: "*.pdf",
192206
tarBall: false,
193207
zipBall: false,
208+
extractAssets: false,
194209
outFilePath: outputFilePath
195210
}
196211
const result = await downloader.download(downloadSettings)
@@ -206,6 +221,7 @@ test("Download a csv file with wildcard filename", async () => {
206221
fileName: "*.csv",
207222
tarBall: false,
208223
zipBall: false,
224+
extractAssets: false,
209225
outFilePath: outputFilePath
210226
}
211227
const result = await downloader.download(downloadSettings)
@@ -223,6 +239,7 @@ test("Download file from Github Enterprise server", async () => {
223239
fileName: "test-1.txt",
224240
tarBall: false,
225241
zipBall: false,
242+
extractAssets: false,
226243
outFilePath: outputFilePath
227244
}
228245
const result = await downloader.download(downloadSettings)
@@ -238,8 +255,34 @@ test("Download file from release identified by ID", async () => {
238255
fileName: "test-2.txt",
239256
tarBall: false,
240257
zipBall: false,
258+
extractAssets: false,
241259
outFilePath: outputFilePath
242260
}
243261
const result = await downloader.download(downloadSettings)
244262
expect(result.length).toBe(1)
245263
}, 10000)
264+
265+
test("Download all archive files from public repo", async () => {
266+
const downloadSettings: IReleaseDownloadSettings = {
267+
sourceRepoPath: "robinraju/probable-potato",
268+
isLatest: true,
269+
tag: "",
270+
id: "",
271+
fileName: "*.zip",
272+
tarBall: false,
273+
zipBall: false,
274+
extractAssets: true,
275+
outFilePath: outputFilePath
276+
}
277+
const result = await downloader.download(downloadSettings)
278+
if (downloadSettings.extractAssets) {
279+
for (const asset of result) {
280+
await extract(asset, downloadSettings.outFilePath)
281+
}
282+
}
283+
284+
expect(result.length).toBe(1)
285+
expect(
286+
fs.existsSync(path.join(downloadSettings.outFilePath, "test-3.txt"))
287+
).toBe(true)
288+
}, 10000)

__tests__/resource/1-release-latest.json

+15
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,21 @@
103103
"created_at": "2022-05-29T12:08:23Z",
104104
"updated_at": "2022-05-29T12:08:23Z",
105105
"browser_download_url": "https://github.com/robinraju/probable-potato/releases/download/1.0.1/file_example.csv"
106+
},
107+
{
108+
"url": "https://api.github.com/repos/robinraju/probable-potato/releases/assets/66946552",
109+
"id": 66946552,
110+
"node_id": "RA_kwDOHahpL84D_YXa",
111+
"name": "archive-example.zip",
112+
"label": null,
113+
"uploader": {},
114+
"content_type": "application/zip",
115+
"state": "uploaded",
116+
"size": 7253,
117+
"download_count": 56,
118+
"created_at": "2022-05-29T12:08:23Z",
119+
"updated_at": "2022-05-29T12:08:23Z",
120+
"browser_download_url": "https://github.com/robinraju/probable-potato/releases/download/1.0.1/archive-example.zip"
106121
}
107122
],
108123
"tarball_url": "https://api.github.com/repos/robinraju/probable-potato/tarball/1.0.1",
306 Bytes
Binary file not shown.

action.yml

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ inputs:
3030
description: "Relative path under $GITHUB_WORKSPACE to place the downloaded files"
3131
default: "."
3232
required: true
33+
extract:
34+
description: "If the downladed assets should be extracted to `out-file-path`. Supports tar, tar.gz and zip"
35+
default: "false"
36+
required: false
3337
token:
3438
description: "Github token to access private repos"
3539
default: ${{ github.token }}

0 commit comments

Comments
 (0)