Update project config and dependencies (#723)

* Update linter config and dependencies

* Remove source map
This commit is contained in:
Robin Raju authored and GitHub committed 2024-04-24 17:48:10 +01:00
1 parent cb096d8fa1
commit 6c76fddc2c
27 files changed
+10934 -9250

No files matched your search

+2 -1
View File
@@ -1,3 +1,4 @@
dist/ dist/
lib/ lib/
node_modules/ node_modules/
coverage/
-55
View File
@@ -1,55 +0,0 @@
{
"plugins": ["jest", "@typescript-eslint", "github", "prettier"],
"extends": ["plugin:github/recommended", "plugin:prettier/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module",
"project": "./tsconfig.json"
},
"rules": {
"eslint-comments/no-use": "off",
"import/no-namespace": "off",
"i18n-text/no-en": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
"@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/array-type": "error",
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/ban-ts-comment": "error",
"camelcase": "off",
"@typescript-eslint/consistent-type-assertions": "error",
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
"@typescript-eslint/func-call-spacing": ["error", "never"],
"@typescript-eslint/no-array-constructor": "error",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-extraneous-class": "error",
"@typescript-eslint/no-for-in-array": "error",
"@typescript-eslint/no-inferrable-types": "error",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-unnecessary-qualifier": "error",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-useless-constructor": "error",
"@typescript-eslint/no-var-requires": "error",
"@typescript-eslint/prefer-for-of": "warn",
"@typescript-eslint/prefer-function-type": "warn",
"@typescript-eslint/prefer-includes": "error",
"@typescript-eslint/prefer-string-starts-ends-with": "error",
"@typescript-eslint/promise-function-async": "error",
"@typescript-eslint/require-array-sort-compare": "error",
"@typescript-eslint/restrict-plus-operands": "error",
"semi": "off",
"@typescript-eslint/semi": ["error", "never"],
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/unbound-method": "error"
},
"env": {
"node": true,
"es6": true,
"jest/globals": true
}
}
+9 -12
View File
@@ -4,27 +4,24 @@ about: Create a report to help us improve
title: '' title: ''
labels: '' labels: ''
assignees: '' assignees: ''
--- ---
**Describe the bug** **Describe the bug** A clear and concise description of what the bug is.
A clear and concise description of what the bug is.
**To Reproduce** Steps to reproduce the behavior:
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...' 1. Go to '...'
2. Click on '....' 2. Click on '....'
3. Scroll down to '....' 3. Scroll down to '....'
4. See error 4. See error
**Expected behavior** **Expected behavior** A clear and concise description of what you expected to
A clear and concise description of what you expected to happen. happen.
**Screenshots** **Screenshots** If applicable, add screenshots to help explain your problem.
If applicable, add screenshots to help explain your problem.
**Action Environment (please complete the following information):** **Action Environment (please complete the following information):**
- OS: [e.g. ubuntu-latest]
**Additional context** - OS: [e.g. ubuntu-latest]
Add any other context about the problem here.
**Additional context** Add any other context about the problem here.
+8 -9
View File
@@ -4,17 +4,16 @@ about: Suggest an idea for this project
title: '' title: ''
labels: '' labels: ''
assignees: '' assignees: ''
--- ---
**Is your feature request related to a problem? Please describe.** **Is your feature request related to a problem? Please describe.** A clear and
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like** **Describe the solution you'd like** A clear and concise description of what you
A clear and concise description of what you want to happen. want to happen.
**Describe alternatives you've considered** **Describe alternatives you've considered** A clear and concise description of
A clear and concise description of any alternative solutions or features you've considered. any alternative solutions or features you've considered.
**Additional context** **Additional context** Add any other context or screenshots about the feature
Add any other context or screenshots about the feature request here. request here.
+22 -11
View File
@@ -1,15 +1,26 @@
# Enable dependabot on this repo to update dependencies periodically.
version: 2 version: 2
updates: updates:
# Enable version updates for npm - package-ecosystem: github-actions
- package-ecosystem: "npm" directory: /
# Look for `package.json` and `lock` files in the `root` directory
directory: "/"
# Check the npm registry for updates every day (weekdays)
schedule: schedule:
interval: "weekly" interval: weekly
# Enable version updates for github actions groups:
- package-ecosystem: "github-actions" actions-minor:
directory: "/" update-types:
- minor
- patch
- package-ecosystem: npm
directory: /
schedule: schedule:
interval: "weekly" interval: weekly
groups:
npm-development:
dependency-type: development
update-types:
- minor
- patch
npm-production:
dependency-type: production
update-types:
- patch
+83
View File
@@ -0,0 +1,83 @@
env:
node: true
es6: true
jest: true
globals:
Atomics: readonly
SharedArrayBuffer: readonly
ignorePatterns:
- '!.*'
- '**/node_modules/.*'
- '**/dist/.*'
- '**/coverage/.*'
- '*.json'
parser: '@typescript-eslint/parser'
parserOptions:
ecmaVersion: 2023
sourceType: module
project:
- './.github/linters/tsconfig.json'
- './tsconfig.json'
plugins:
- jest
- '@typescript-eslint'
extends:
- eslint:recommended
- plugin:@typescript-eslint/eslint-recommended
- plugin:@typescript-eslint/recommended
- plugin:github/recommended
- plugin:jest/recommended
rules:
{
'camelcase': 'off',
'eslint-comments/no-use': 'off',
'eslint-comments/no-unused-disable': 'off',
'i18n-text/no-en': 'off',
'import/no-namespace': 'off',
'no-console': 'off',
'no-unused-vars': 'off',
'prettier/prettier': 'error',
'semi': 'off',
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/consistent-type-assertions': 'error',
'@typescript-eslint/explicit-member-accessibility':
['error', { 'accessibility': 'no-public' }],
'@typescript-eslint/explicit-function-return-type':
['error', { 'allowExpressions': true }],
'@typescript-eslint/func-call-spacing': ['error', 'never'],
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-empty-interface': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-extraneous-class': 'error',
'@typescript-eslint/no-for-in-array': 'error',
'@typescript-eslint/no-inferrable-types': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-namespace': 'error',
'@typescript-eslint/no-non-null-assertion': 'warn',
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-unnecessary-qualifier': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/no-var-requires': 'error',
'@typescript-eslint/prefer-for-of': 'warn',
'@typescript-eslint/prefer-function-type': 'warn',
'@typescript-eslint/prefer-includes': 'error',
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
'@typescript-eslint/promise-function-async': 'error',
'@typescript-eslint/require-array-sort-compare': 'error',
'@typescript-eslint/restrict-plus-operands': 'error',
'@typescript-eslint/semi': ['error', 'never'],
'@typescript-eslint/space-before-function-paren': 'off',
'@typescript-eslint/type-annotation-spacing': 'error',
'@typescript-eslint/unbound-method': 'error'
}
+18
View File
@@ -0,0 +1,18 @@
# Unordered list style
MD004:
style: dash
# Ordered list item prefix
MD029:
style: one
# Spaces after list markers
MD030:
ul_single: 1
ol_single: 1
ul_multi: 1
ol_multi: 1
# Code block style
MD046:
style: fenced
+10
View File
@@ -0,0 +1,10 @@
rules:
document-end: disable
document-start:
level: warning
present: false
line-length:
level: warning
max: 80
allow-non-breakable-words: true
allow-non-breakable-inline-mappings: true
+9
View File
@@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "../../tsconfig.json",
"compilerOptions": {
"noEmit": true
},
"include": ["../../__tests__/**/*", "../../src/**/*"],
"exclude": ["../../dist", "../../node_modules", "../../coverage", "*.json"]
}
+83 -84
View File
@@ -1,11 +1,11 @@
name: "Build and Test" name: 'Build and Test'
on: on:
# Trigger manually # Trigger manually
workflow_dispatch: workflow_dispatch:
pull_request: pull_request:
push: push:
tags: tags:
- "*" - '*'
branches: branches:
- main - main
@@ -18,96 +18,95 @@ jobs:
- macos-latest - macos-latest
- windows-latest - windows-latest
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- name: Checkout Repo
- name: Checkout Repo uses: actions/checkout@v4
uses: actions/checkout@v4
- name: Setup node and cache dependencies - name: Setup node and cache dependencies
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20
cache: 'npm' cache: 'npm'
- name: Build and test - name: Build and test
shell: bash shell: bash
run: | run: |
npm ci npm ci
npm run all npm run all
- name: Run action
uses: ./
id: download-public
with:
repository: "robinraju/probable-potato"
tag: "1.0.1"
fileName: "potato.jpeg"
tarBall: true
zipBall: true
out-file-path: "./test-downloads"
- name: List downloaded files
shell: bash
run: ls -lrth test-downloads
- name: Download tarBall & zipBall only - name: Run action
uses: ./ uses: ./
with: id: download-public
repository: "robinraju/probable-potato" with:
tag: "1.0.2" repository: 'robinraju/probable-potato'
tarBall: true tag: '1.0.1'
zipBall: true fileName: 'potato.jpeg'
out-file-path: "./public-download" tarBall: true
zipBall: true
out-file-path: './test-downloads'
- name: List downloaded files - name: List downloaded files
shell: bash shell: bash
run: ls -lrth public-download run: ls -lrth test-downloads
- name: Test download latest pre-release
uses: ./
with:
repository: "robinraju/probable-potato"
latest: true
preRelease: true
fileName: "prerelease.txt"
tarBall: true
zipBall: true
out-file-path: "./prerelease-downloads"
- name: List downloaded files - name: Download tarBall & zipBall only
shell: bash uses: ./
run: ls -lrth prerelease-downloads with:
repository: 'robinraju/probable-potato'
tag: '1.0.2'
tarBall: true
zipBall: true
out-file-path: './public-download'
- name: Test download from a private repo - name: List downloaded files
uses: ./ shell: bash
id: download-private run: ls -lrth public-download
with:
repository: "robinraju/release-downloader-test"
latest: true
fileName: "*"
tarBall: true
zipBall: true
extract: true
token: ${{ secrets.RELEASE_DOWNLOADER_TEST_TOKEN }}
out-file-path: "./downloader-test"
- name: List downloaded files from private repo - name: Test download latest pre-release
shell: bash uses: ./
run: ls -lrth downloader-test with:
repository: 'robinraju/probable-potato'
latest: true
preRelease: true
fileName: 'prerelease.txt'
tarBall: true
zipBall: true
out-file-path: './prerelease-downloads'
- name: Read output variable set by previous steps - name: List downloaded files
shell: bash shell: bash
run: | run: ls -lrth prerelease-downloads
if [ -n ${{steps.download-public.outputs.tag_name}} ]; then
echo ${{steps.download-public.outputs.tag_name}}
else echo "Unable to read output variable from step download-public"; exit 1
fi
if [ -n ${{steps.download-private.outputs.tag_name}} ]; then - name: Test download from a private repo
echo ${{steps.download-private.outputs.tag_name}} uses: ./
else echo "Unable to read output variable from step download-private"; exit 1 id: download-private
fi with:
repository: 'robinraju/release-downloader-test'
latest: true
fileName: '*'
tarBall: true
zipBall: true
extract: true
token: ${{ secrets.RELEASE_DOWNLOADER_TEST_TOKEN }}
out-file-path: './downloader-test'
echo "Downloaded files:" - name: List downloaded files from private repo
echo ${{steps.download-public.outputs.downloaded_files}} shell: bash
run: ls -lrth downloader-test
- name: Read output variable set by previous steps
shell: bash
run: |
if [ -n ${{steps.download-public.outputs.tag_name}} ]; then
echo ${{steps.download-public.outputs.tag_name}}
else echo "Unable to read output variable from step download-public"; exit 1
fi
if [ -n ${{steps.download-private.outputs.tag_name}} ]; then
echo ${{steps.download-private.outputs.tag_name}}
else echo "Unable to read output variable from step download-private"; exit 1
fi
echo "Downloaded files:"
echo ${{steps.download-public.outputs.downloaded_files}}
+5 -5
View File
@@ -1,12 +1,12 @@
pull_request_rules: pull_request_rules:
- name: Automatic merge PR by dependabot - name: Automatic merge PR by dependabot
conditions: conditions:
- "author=dependabot[bot]" - 'author=dependabot[bot]'
- "status-success=build (ubuntu-latest)" - 'status-success=build (ubuntu-latest)'
- "status-success=build (macos-latest)" - 'status-success=build (macos-latest)'
- "status-success=build (windows-latest)" - 'status-success=build (windows-latest)'
actions: actions:
merge: merge:
method: squash method: squash
delete_head_branch: delete_head_branch:
force: true force: true
+8 -3
View File
@@ -3,9 +3,14 @@
"tabWidth": 2, "tabWidth": 2,
"useTabs": false, "useTabs": false,
"semi": false, "semi": false,
"singleQuote": false, "singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"trailingComma": "none", "trailingComma": "none",
"bracketSpacing": false, "bracketSpacing": true,
"bracketSameLine": true,
"arrowParens": "avoid", "arrowParens": "avoid",
"parser": "typescript" "proseWrap": "always",
"htmlWhitespaceSensitivity": "css",
"endOfLine": "lf"
} }
+34 -22
View File
@@ -5,19 +5,22 @@
- Node > v12.x - Node > v12.x
- npm - npm
Install the dependencies Install dependencies
```bash ```bash
$ npm install npm install
``` ```
Build the typescript and package it for distribution Build typescript and package it for distribution
```bash ```bash
$ npm run build && npm run pack npm run build && npm run pack
``` ```
Run the tests :heavy_check_mark: Run tests :heavy_check_mark:
```bash ```bash
$ npm test npm test
PASS __tests__/main.test.ts PASS __tests__/main.test.ts
✓ run download (1207ms) ✓ run download (1207ms)
@@ -35,22 +38,25 @@ Ran all test suites.
The action.yml contains defines the inputs and output for your action. The action.yml contains defines the inputs and output for your action.
Update the action.yml with your name, description, inputs and outputs for your action. Update the action.yml with your name, description, inputs and outputs for your
action.
See the [documentation](https://help.github.com/en/articles/metadata-syntax-for-github-actions) See the
[documentation](https://help.github.com/en/articles/metadata-syntax-for-github-actions)
## Change the Code ## Change the Code
Most toolkit and CI/CD operations involve async operations so the action is run in an async function. Most toolkit and CI/CD operations involve async operations so the action is run
in an async function.
```javascript ```javascript
import * as core from '@actions/core'; import * as core from '@actions/core';
... ...
async function run() { async function run() {
try { try {
... ...
} }
catch (error) { catch (error) {
core.setFailed(error.message); core.setFailed(error.message);
} }
@@ -59,13 +65,16 @@ async function run() {
run() run()
``` ```
See the [toolkit documentation](https://github.com/actions/toolkit/blob/master/README.md#packages) for the various packages. See the
[toolkit documentation](https://github.com/actions/toolkit/blob/master/README.md#packages)
for the various packages.
## Publish to a distribution branch ## Publish to a distribution branch
Actions are run from GitHub repos so we will checkin the packed dist folder. Actions are run from GitHub repos so we will checkin the packed dist folder.
Then run [ncc](https://github.com/zeit/ncc) and push the results: Then run [ncc](https://github.com/zeit/ncc) and push the results:
```bash ```bash
$ npm run package $ npm run package
$ git add dist $ git add dist
@@ -73,21 +82,24 @@ $ git commit -a -m "prod dependencies"
$ git push origin releases/v1 $ git push origin releases/v1
``` ```
Your action is now published! :rocket: Your action is now published! :rocket:
See the [versioning documentation](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md) See the
[versioning documentation](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md)
## Validate ## Validate
You can now validate the action by referencing `./` in a workflow in your repo (see [test.yml](.github/workflows/test.yml)) You can now validate the action by referencing `./` in a workflow in your repo
(see [test.yml](.github/workflows/test.yml))
```yaml ```yaml
uses: ./ uses: ./
with: with:
repository: "user/repo" repository: 'user/repo'
tag: "1.0.0" tag: '1.0.0'
fileName: "foo.zip" fileName: 'foo.zip'
out-file-path: "." out-file-path: '.'
``` ```
See the [actions tab](https://github.com/actions/javascript-action/actions) for runs of this action! :rocket: See the [actions tab](https://github.com/actions/javascript-action/actions) for
runs of this action! :rocket:
+55 -51
View File
@@ -1,20 +1,20 @@
## Github Release Downloader # Github Release Downloader
[![Build and Test](https://github.com/robinraju/release-downloader/actions/workflows/ci.yml/badge.svg)](https://github.com/robinraju/release-downloader/actions/workflows/ci.yml) [![Build and Test](https://github.com/robinraju/release-downloader/actions/workflows/ci.yml/badge.svg)](https://github.com/robinraju/release-downloader/actions/workflows/ci.yml)
A Github Action to download assets from github release. It can download specified files from both private and public repositories. A Github Action to download assets from Github release. It can download
specified files from both private and public repositories.
## Usage ## Usage
```yaml ```yaml
- uses: robinraju/release-downloader@v1.10 - uses: robinraju/release-downloader@v1.10
with: with:
# The source repository path. # The source repository path.
# Expected format {owner}/{repo} # Expected format {owner}/{repo}
# Default: ${{ github.repository }} # Default: ${{ github.repository }}
repository: "" repository: ''
# A flag to set the download target as latest release # A flag to set the download target as latest release
# The default value is 'false' # The default value is 'false'
latest: true latest: true
@@ -22,29 +22,29 @@ A Github Action to download assets from github release. It can download specifie
# A flag to download from prerelease. It should be combined with latest flag. # A flag to download from prerelease. It should be combined with latest flag.
# The default value is 'false' # The default value is 'false'
preRelease: true preRelease: true
# The github tag. e.g: v1.0.1 # The github tag. e.g: v1.0.1
# Download assets from a specific tag/version # Download assets from a specific tag/version
tag: "" tag: ''
# The release id to download files from # The release id to download files from
releaseId: "" releaseId: ''
# The name of the file to download. # The name of the file to download.
# Use this field only to specify filenames other than tarball or zipball, if any. # Use this field only to specify filenames other than tarball or zipball, if any.
# Supports wildcard pattern (eg: '*', '*.deb', '*.zip' etc..) # Supports wildcard pattern (eg: '*', '*.deb', '*.zip' etc..)
fileName: "" fileName: ''
# Download the attached tarball (*.tar.gz) # Download the attached tarball (*.tar.gz)
tarBall: true tarBall: true
# Download the attached zipball (*.zip) # Download the attached zipball (*.zip)
zipBall: true zipBall: true
# Relative path under $GITHUB_WORKSPACE to place the downloaded file(s) # Relative path under $GITHUB_WORKSPACE to place the downloaded file(s)
# It will create the target directory automatically if not present # It will create the target directory automatically if not present
# eg: out-file-path: "my-downloads" => It will create directory $GITHUB_WORKSPACE/my-downloads # eg: out-file-path: "my-downloads" => It will create directory $GITHUB_WORKSPACE/my-downloads
out-file-path: "" out-file-path: ''
# A flag to set if the downloaded assets are archives and should be extracted # A flag to set if the downloaded assets are archives and should be extracted
# Checks all downloaded files if they end with zip, tar or tar.gz and extracts them, if true. # Checks all downloaded files if they end with zip, tar or tar.gz and extracts them, if true.
@@ -54,79 +54,83 @@ A Github Action to download assets from github release. It can download specifie
# Github access token to download files from private repositories # Github access token to download files from private repositories
# https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets # https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets
# eg: token: ${{ secrets.MY_TOKEN }} # eg: token: ${{ secrets.MY_TOKEN }}
token: "" token: ''
# The URL of the Github API, only use this input if you are using Github Enterprise # The URL of the Github API, only use this input if you are using Github Enterprise
# Default: "https://api.github.com" # Default: "https://api.github.com"
# Use http(s)://[hostname]/api/v3 to access the API for GitHub Enterprise Server # Use http(s)://[hostname]/api/v3 to access the API for GitHub Enterprise Server
github-api-url: "" github-api-url: ''
``` ```
#### Output variables ### Output variables
- `tag_name` it outputs the tag used to download a release. - `tag_name` it outputs the tag used to download a release.
> This variable can be used by other actions as an input as follows > This variable can be used by other actions as an input as follows
> ```
> ${{steps.<step-id>.outputs.tag_name}} ```sh
> ``` ${{steps.<step-id>.outputs.tag_name}}
```
- `release_name` it outputs the name/title of the release - `release_name` it outputs the name/title of the release
> It can ce used as follows
> ``` It can be used as follows
> ${{steps.<step-id>.outputs.release_name}}
>``` ```sh
${{steps.<step-id>.outputs.release_name}}
```
- `downloaded_files` it outputs an array of downloaded files - `downloaded_files` it outputs an array of downloaded files
> It can be used as follows It can be used as follows
>
> `${{ fromJson(steps.<step-id>.outputs.downloaded_files)[0] }}` ```sh
${{ fromJson(steps.<step-id>.outputs.downloaded_files)[0] }}
```
## Scenarios ## Scenarios
### Download asset from the latest release in the current repository ### Download asset from the latest release in the current repository
```yaml ```yaml
- uses: robinraju/release-downloader@v1.10 - uses: robinraju/release-downloader@v1.10
with: with:
latest: true latest: true
fileName: "foo.zip" fileName: 'foo.zip'
``` ```
### Download asset from a specific release version. ### Download asset from a specific release version
```yaml ```yaml
- uses: robinraju/release-downloader@v1.10 - uses: robinraju/release-downloader@v1.10
with: with:
repository: "owner/repo" repository: 'owner/repo'
tag: "v1.0.0" tag: 'v1.0.0'
fileName: "foo.zip" fileName: 'foo.zip'
``` ```
### Download tarball and zipball ### Download tarball and zipball
```yaml ```yaml
- uses: robinraju/release-downloader@v1.10 - uses: robinraju/release-downloader@v1.10
with: with:
repository: "owner/repo" repository: 'owner/repo'
latest: true latest: true
tarBall: true tarBall: true
zipBall: true zipBall: true
``` ```
> Remove the `latest` flag and specify `tag` if you want to download from a different release.
> Remove the `latest` flag and specify `tag` if you want to download from a
> different release.
### Download multiple assets ### Download multiple assets
```yaml ```yaml
- uses: robinraju/release-downloader@v1.10 - uses: robinraju/release-downloader@v1.10
with: with:
repository: "owner/repo" repository: 'owner/repo'
latest: true latest: true
fileName: "foo.zip" fileName: 'foo.zip'
tarBall: true tarBall: true
zipBall: true zipBall: true
``` ```
@@ -136,9 +140,9 @@ A Github Action to download assets from github release. It can download specifie
```yaml ```yaml
- uses: robinraju/release-downloader@v1.10 - uses: robinraju/release-downloader@v1.10
with: with:
repository: "owner/repo" repository: 'owner/repo'
latest: true latest: true
fileName: "*" fileName: '*'
``` ```
### Download assets using wildcard pattern ### Download assets using wildcard pattern
@@ -146,9 +150,9 @@ A Github Action to download assets from github release. It can download specifie
```yaml ```yaml
- uses: robinraju/release-downloader@v1.10 - uses: robinraju/release-downloader@v1.10
with: with:
repository: "owner/repo" repository: 'owner/repo'
latest: true latest: true
fileName: "*.deb" fileName: '*.deb'
``` ```
### Download a release using its id ### Download a release using its id
@@ -156,8 +160,8 @@ A Github Action to download assets from github release. It can download specifie
```yaml ```yaml
- uses: robinraju/release-downloader@v1.10 - uses: robinraju/release-downloader@v1.10
with: with:
releaseId: "123123" releaseId: '123123'
fileName: "foo.zip" fileName: 'foo.zip'
``` ```
### Download and extracts archives ### Download and extracts archives
@@ -165,7 +169,7 @@ A Github Action to download assets from github release. It can download specifie
```yaml ```yaml
- uses: robinraju/release-downloader@v1.10 - uses: robinraju/release-downloader@v1.10
with: with:
fileName: "foo.zip" fileName: 'foo.zip'
latest: true latest: true
extract: true extract: true
``` ```
@@ -175,8 +179,8 @@ A Github Action to download assets from github release. It can download specifie
```yaml ```yaml
- uses: robinraju/release-downloader@v1.10 - uses: robinraju/release-downloader@v1.10
with: with:
repository: "owner/repo" repository: 'owner/repo'
fileName: "foo.zip" fileName: 'foo.zip'
latest: true latest: true
preRelease: true preRelease: true
``` ```
+166 -164
View File
@@ -1,127 +1,127 @@
import * as fs from "fs" import * as fs from 'fs'
import * as path from "path" import * as path from 'path'
import * as handlers from "typed-rest-client/Handlers" import * as handlers from 'typed-rest-client/Handlers'
import * as io from "@actions/io" import * as io from '@actions/io'
import * as thc from "typed-rest-client/HttpClient" import * as thc from 'typed-rest-client/HttpClient'
import {IReleaseDownloadSettings} from "../src/download-settings" import { IReleaseDownloadSettings } from '../src/download-settings'
import {ReleaseDownloader} from "../src/release-downloader" import { ReleaseDownloader } from '../src/release-downloader'
import nock from "nock" import nock from 'nock'
import {extract} from "../src/unarchive" import { extract } from '../src/unarchive'
let downloader: ReleaseDownloader let downloader: ReleaseDownloader
let httpClent: thc.HttpClient let httpClent: thc.HttpClient
const outputFilePath = "./test-output" const outputFilePath = './test-output'
beforeEach(() => { beforeEach(() => {
const githubtoken = process.env.REPO_TOKEN || "" const githubtoken = process.env.REPO_TOKEN || ''
const githubApiUrl = "https://api.github.com" const githubApiUrl = 'https://api.github.com'
const credentialHandler = new handlers.BearerCredentialHandler( const credentialHandler = new handlers.BearerCredentialHandler(
githubtoken, githubtoken,
false false
) )
httpClent = new thc.HttpClient("gh-api-client", [credentialHandler]) httpClent = new thc.HttpClient('gh-api-client', [credentialHandler])
downloader = new ReleaseDownloader(httpClent, githubApiUrl) downloader = new ReleaseDownloader(httpClent, githubApiUrl)
nock("https://api.github.com") nock('https://api.github.com')
.get("/repos/robinraju/probable-potato/releases/latest") .get('/repos/robinraju/probable-potato/releases/latest')
.reply(200, readFromFile("1-release-latest.json")) .reply(200, readFromFile('1-release-latest.json'))
nock("https://api.github.com") nock('https://api.github.com')
.get("/repos/robinraju/probable-potato/releases/68092191") .get('/repos/robinraju/probable-potato/releases/68092191')
.reply(200, readFromFile("1-release-latest.json")) .reply(200, readFromFile('1-release-latest.json'))
nock("https://api.github.com") nock('https://api.github.com')
.get("/repos/robinraju/foo-app/releases/tags/1.0.0") .get('/repos/robinraju/foo-app/releases/tags/1.0.0')
.reply(200, readFromFile("3-empty-assets.json")) .reply(200, readFromFile('3-empty-assets.json'))
nock("https://api.github.com", { nock('https://api.github.com', {
reqheaders: {accept: "application/octet-stream"} reqheaders: { accept: 'application/octet-stream' }
}) })
.get("/repos/robinraju/probable-potato/releases/assets/66946546") .get('/repos/robinraju/probable-potato/releases/assets/66946546')
.replyWithFile(200, __dirname + "/resource/assets/test-1.txt") .replyWithFile(200, `${__dirname}/resource/assets/test-1.txt`)
nock("https://api.github.com", { nock('https://api.github.com', {
reqheaders: {accept: "application/octet-stream"} reqheaders: { accept: 'application/octet-stream' }
}) })
.get("/repos/robinraju/probable-potato/releases/assets/66946547") .get('/repos/robinraju/probable-potato/releases/assets/66946547')
.replyWithFile(200, __dirname + "/resource/assets/test-2.txt") .replyWithFile(200, `${__dirname}/resource/assets/test-2.txt`)
nock("https://api.github.com", { nock('https://api.github.com', {
reqheaders: {accept: "application/octet-stream"} reqheaders: { accept: 'application/octet-stream' }
}) })
.get("/repos/robinraju/probable-potato/releases/assets/66946548") .get('/repos/robinraju/probable-potato/releases/assets/66946548')
.replyWithFile(200, __dirname + "/resource/assets/3-test.txt") .replyWithFile(200, `${__dirname}/resource/assets/3-test.txt`)
nock("https://api.github.com", { nock('https://api.github.com', {
reqheaders: {accept: "application/octet-stream"} reqheaders: { accept: 'application/octet-stream' }
}) })
.get("/repos/robinraju/probable-potato/releases/assets/66946549") .get('/repos/robinraju/probable-potato/releases/assets/66946549')
.replyWithFile(200, __dirname + "/resource/assets/downloader-test.pdf") .replyWithFile(200, `${__dirname}/resource/assets/downloader-test.pdf`)
nock("https://api.github.com", { nock('https://api.github.com', {
reqheaders: {accept: "application/octet-stream"} reqheaders: { accept: 'application/octet-stream' }
}) })
.get("/repos/robinraju/probable-potato/releases/assets/66946550") .get('/repos/robinraju/probable-potato/releases/assets/66946550')
.replyWithFile(200, __dirname + "/resource/assets/lorem-ipsum.pdf") .replyWithFile(200, `${__dirname}/resource/assets/lorem-ipsum.pdf`)
nock("https://api.github.com", { nock('https://api.github.com', {
reqheaders: {accept: "application/octet-stream"} reqheaders: { accept: 'application/octet-stream' }
}) })
.get("/repos/robinraju/probable-potato/releases/assets/66946552") .get('/repos/robinraju/probable-potato/releases/assets/66946552')
.replyWithFile(200, __dirname + "/resource/assets/archive-example.zip") .replyWithFile(200, `${__dirname}/resource/assets/archive-example.zip`)
nock("https://api.github.com", { nock('https://api.github.com', {
reqheaders: {accept: "application/octet-stream"} reqheaders: { accept: 'application/octet-stream' }
}) })
.get("/repos/robinraju/probable-potato/releases/assets/66946551") .get('/repos/robinraju/probable-potato/releases/assets/66946551')
.replyWithFile(200, __dirname + "/resource/assets/file_example.csv") .replyWithFile(200, `${__dirname}/resource/assets/file_example.csv`)
nock("https://my-gh-host.com/api/v3") nock('https://my-gh-host.com/api/v3')
.get("/repos/my-enterprise/test-repo/releases/latest") .get('/repos/my-enterprise/test-repo/releases/latest')
.reply(200, readFromFile("2-gh-enterprise.json")) .reply(200, readFromFile('2-gh-enterprise.json'))
nock("https://my-gh-host.com/api/v3", { nock('https://my-gh-host.com/api/v3', {
reqheaders: {accept: "application/octet-stream"} reqheaders: { accept: 'application/octet-stream' }
}) })
.get("/repos/my-enterprise/test-repo/releases/assets/66946546") .get('/repos/my-enterprise/test-repo/releases/assets/66946546')
.replyWithFile(200, __dirname + "/resource/assets/test-1.txt") .replyWithFile(200, `${__dirname}/resource/assets/test-1.txt`)
nock("https://api.github.com/") nock('https://api.github.com/')
.get("/repos/robinraju/slick-pg/releases") .get('/repos/robinraju/slick-pg/releases')
.reply(200, readFromFile("4-with-prerelease.json")) .reply(200, readFromFile('4-with-prerelease.json'))
nock("https://api.github.com", { nock('https://api.github.com', {
reqheaders: {accept: "application/octet-stream"} reqheaders: { accept: 'application/octet-stream' }
}) })
.get("/repos/robinraju/slick-pg/releases/assets/66946546") .get('/repos/robinraju/slick-pg/releases/assets/66946546')
.replyWithFile(200, __dirname + "/resource/assets/pre-release.txt") .replyWithFile(200, `${__dirname}/resource/assets/pre-release.txt`)
nock("https://api.github.com/") nock('https://api.github.com/')
.get("/repos/foo/slick-pg/releases") .get('/repos/foo/slick-pg/releases')
.reply(200, readFromFile("5-without-prerelease.json")) .reply(200, readFromFile('5-without-prerelease.json'))
nock("https://api.github.com") nock('https://api.github.com')
.get("/repos/robinraju/tar-zip-ball-only-repo/releases/latest") .get('/repos/robinraju/tar-zip-ball-only-repo/releases/latest')
.reply(200, readFromFile("6-tar-zip-ball-only-repo.json")) .reply(200, readFromFile('6-tar-zip-ball-only-repo.json'))
nock("https://api.github.com", { nock('https://api.github.com', {
reqheaders: {accept: "*/*"} reqheaders: { accept: '*/*' }
}) })
.get("/repos/robinraju/tar-zip-ball-only-repo/tarball/1.0.0") .get('/repos/robinraju/tar-zip-ball-only-repo/tarball/1.0.0')
.replyWithFile( .replyWithFile(
200, 200,
__dirname + "/resource/assets/tar-zip-ball-only-repo.tar.gz" `${__dirname}/resource/assets/tar-zip-ball-only-repo.tar.gz`
) )
nock("https://api.github.com", { nock('https://api.github.com', {
reqheaders: {accept: "*/*"} reqheaders: { accept: '*/*' }
}) })
.get("/repos/robinraju/tar-zip-ball-only-repo/zipball/1.0.0") .get('/repos/robinraju/tar-zip-ball-only-repo/zipball/1.0.0')
.replyWithFile( .replyWithFile(
200, 200,
__dirname + "/resource/assets/tar-zip-ball-only-repo.zip" `${__dirname}/resource/assets/tar-zip-ball-only-repo.zip`
) )
}) })
@@ -131,24 +131,24 @@ afterEach(async () => {
function readFromFile(fileName: string): string { function readFromFile(fileName: string): string {
const fileContents = fs.readFileSync(`${__dirname}/resource/${fileName}`, { const fileContents = fs.readFileSync(`${__dirname}/resource/${fileName}`, {
encoding: "utf-8" encoding: 'utf-8'
}) })
return normalizeLineEndings(fileContents) return normalizeLineEndings(fileContents)
} }
function normalizeLineEndings(str: string): string { function normalizeLineEndings(str: string): string {
// Normalize all line endings to LF (\n) // Normalize all line endings to LF (\n)
return str.replace(/\r\n/g, "\n") return str.replace(/\r\n/g, '\n')
} }
test("Download all files from public repo", async () => { test('Download all files from public repo', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato", sourceRepoPath: 'robinraju/probable-potato',
isLatest: true, isLatest: true,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "*", fileName: '*',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -158,14 +158,14 @@ test("Download all files from public repo", async () => {
expect(result.length).toBe(7) expect(result.length).toBe(7)
}, 10000) }, 10000)
test("Download single file from public repo", async () => { test('Download single file from public repo', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato", sourceRepoPath: 'robinraju/probable-potato',
isLatest: true, isLatest: true,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "test-1.txt", fileName: 'test-1.txt',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -175,14 +175,14 @@ test("Download single file from public repo", async () => {
expect(result.length).toBe(1) expect(result.length).toBe(1)
}, 10000) }, 10000)
test("Fail loudly if given filename is not found in a release", async () => { test('Fail loudly if given filename is not found in a release', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato", sourceRepoPath: 'robinraju/probable-potato',
isLatest: true, isLatest: true,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "missing-file.txt", fileName: 'missing-file.txt',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -190,18 +190,18 @@ test("Fail loudly if given filename is not found in a release", async () => {
} }
const result = downloader.download(downloadSettings) const result = downloader.download(downloadSettings)
await expect(result).rejects.toThrow( await expect(result).rejects.toThrow(
"Asset with name missing-file.txt not found!" 'Asset with name missing-file.txt not found!'
) )
}, 10000) }, 10000)
test("Fail loudly if release is not identified", async () => { test('Fail loudly if release is not identified', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato", sourceRepoPath: 'robinraju/probable-potato',
isLatest: false, isLatest: false,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "missing-file.txt", fileName: 'missing-file.txt',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -209,18 +209,18 @@ test("Fail loudly if release is not identified", async () => {
} }
const result = downloader.download(downloadSettings) const result = downloader.download(downloadSettings)
await expect(result).rejects.toThrow( await expect(result).rejects.toThrow(
"Config error: Please input a valid tag or release ID, or specify `latest`" 'Config error: Please input a valid tag or release ID, or specify `latest`'
) )
}, 10000) }, 10000)
test("Download files with wildcard from public repo", async () => { test('Download files with wildcard from public repo', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato", sourceRepoPath: 'robinraju/probable-potato',
isLatest: true, isLatest: true,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "test-*.txt", fileName: 'test-*.txt',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -230,14 +230,14 @@ test("Download files with wildcard from public repo", async () => {
expect(result.length).toBe(2) expect(result.length).toBe(2)
}, 10000) }, 10000)
test("Download single file with wildcard from public repo", async () => { test('Download single file with wildcard from public repo', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato", sourceRepoPath: 'robinraju/probable-potato',
isLatest: true, isLatest: true,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "3-*.txt", fileName: '3-*.txt',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -247,14 +247,14 @@ test("Download single file with wildcard from public repo", async () => {
expect(result.length).toBe(1) expect(result.length).toBe(1)
}, 10000) }, 10000)
test("Download multiple pdf files with wildcard filename", async () => { test('Download multiple pdf files with wildcard filename', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato", sourceRepoPath: 'robinraju/probable-potato',
isLatest: true, isLatest: true,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "*.pdf", fileName: '*.pdf',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -264,14 +264,14 @@ test("Download multiple pdf files with wildcard filename", async () => {
expect(result.length).toBe(2) expect(result.length).toBe(2)
}, 10000) }, 10000)
test("Download a csv file with wildcard filename", async () => { test('Download a csv file with wildcard filename', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato", sourceRepoPath: 'robinraju/probable-potato',
isLatest: true, isLatest: true,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "*.csv", fileName: '*.csv',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -281,16 +281,16 @@ test("Download a csv file with wildcard filename", async () => {
expect(result.length).toBe(1) expect(result.length).toBe(1)
}, 10000) }, 10000)
test("Download file from Github Enterprise server", async () => { test('Download file from Github Enterprise server', async () => {
downloader = new ReleaseDownloader(httpClent, "https://my-gh-host.com/api/v3") downloader = new ReleaseDownloader(httpClent, 'https://my-gh-host.com/api/v3')
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "my-enterprise/test-repo", sourceRepoPath: 'my-enterprise/test-repo',
isLatest: true, isLatest: true,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "test-1.txt", fileName: 'test-1.txt',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -300,14 +300,14 @@ test("Download file from Github Enterprise server", async () => {
expect(result.length).toBe(1) expect(result.length).toBe(1)
}, 10000) }, 10000)
test("Download file from release identified by ID", async () => { test('Download file from release identified by ID', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato", sourceRepoPath: 'robinraju/probable-potato',
isLatest: false, isLatest: false,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "68092191", id: '68092191',
fileName: "test-2.txt", fileName: 'test-2.txt',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -317,14 +317,14 @@ test("Download file from release identified by ID", async () => {
expect(result.length).toBe(1) expect(result.length).toBe(1)
}, 10000) }, 10000)
test("Download all archive files from public repo", async () => { test('Download all archive files from public repo', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato", sourceRepoPath: 'robinraju/probable-potato',
isLatest: true, isLatest: true,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "*.zip", fileName: '*.zip',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: true, extractAssets: true,
@@ -339,29 +339,31 @@ test("Download all archive files from public repo", async () => {
expect(result.length).toBe(1) expect(result.length).toBe(1)
expect( expect(
fs.existsSync(path.join(downloadSettings.outFilePath, "test-3.txt")) fs.existsSync(path.join(downloadSettings.outFilePath, 'test-3.txt'))
).toBe(true) ).toBe(true)
const extractedFilePath = path.join( const extractedFilePath = path.join(
downloadSettings.outFilePath, downloadSettings.outFilePath,
"test-4.txt" 'test-4.txt'
) )
expect(fs.existsSync(extractedFilePath)).toBe(true) expect(fs.existsSync(extractedFilePath)).toBe(true)
const actualContent = fs.readFileSync(extractedFilePath, {encoding: "utf-8"}) const actualContent = fs.readFileSync(extractedFilePath, {
const expectedContent = readFromFile("assets/archive-example-test-4.txt") encoding: 'utf-8'
})
const expectedContent = readFromFile('assets/archive-example-test-4.txt')
expect(normalizeLineEndings(actualContent)).toBe(expectedContent) expect(normalizeLineEndings(actualContent)).toBe(expectedContent)
}, 10000) }, 10000)
test("Fail when a release with no assets are obtained", async () => { test('Fail when a release with no assets are obtained', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/foo-app", sourceRepoPath: 'robinraju/foo-app',
isLatest: false, isLatest: false,
preRelease: false, preRelease: false,
tag: "1.0.0", tag: '1.0.0',
id: "", id: '',
fileName: "installer.zip", fileName: 'installer.zip',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -369,18 +371,18 @@ test("Fail when a release with no assets are obtained", async () => {
} }
const result = downloader.download(downloadSettings) const result = downloader.download(downloadSettings)
await expect(result).rejects.toThrow( await expect(result).rejects.toThrow(
"No assets found in release Foo app - v1.0.0" 'No assets found in release Foo app - v1.0.0'
) )
}, 10000) }, 10000)
test("Download from latest prerelease", async () => { test('Download from latest prerelease', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/slick-pg", sourceRepoPath: 'robinraju/slick-pg',
isLatest: true, isLatest: true,
preRelease: true, preRelease: true,
tag: "", tag: '',
id: "", id: '',
fileName: "pre-release.txt", fileName: 'pre-release.txt',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
@@ -390,31 +392,31 @@ test("Download from latest prerelease", async () => {
expect(result.length).toBe(1) expect(result.length).toBe(1)
}, 10000) }, 10000)
test("Fail when a release with no prerelease is obtained", async () => { test('Fail when a release with no prerelease is obtained', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "foo/slick-pg", sourceRepoPath: 'foo/slick-pg',
isLatest: true, isLatest: true,
preRelease: true, preRelease: true,
tag: "", tag: '',
id: "", id: '',
fileName: "installer.zip", fileName: 'installer.zip',
tarBall: false, tarBall: false,
zipBall: false, zipBall: false,
extractAssets: false, extractAssets: false,
outFilePath: outputFilePath outFilePath: outputFilePath
} }
const result = downloader.download(downloadSettings) const result = downloader.download(downloadSettings)
await expect(result).rejects.toThrow("No prereleases found!") await expect(result).rejects.toThrow('No prereleases found!')
}, 10000) }, 10000)
test("Download from a release containing only tarBall & zipBall", async () => { test('Download from a release containing only tarBall & zipBall', async () => {
const downloadSettings: IReleaseDownloadSettings = { const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/tar-zip-ball-only-repo", sourceRepoPath: 'robinraju/tar-zip-ball-only-repo',
isLatest: true, isLatest: true,
preRelease: false, preRelease: false,
tag: "", tag: '',
id: "", id: '',
fileName: "", fileName: '',
tarBall: true, tarBall: true,
zipBall: true, zipBall: true,
extractAssets: false, extractAssets: false,
+45 -32
View File
@@ -1,66 +1,79 @@
name: "release-downloader" name: 'release-downloader'
description: "Download release assets from private or public github repositories" description:
author: "Robin Raju" 'Download release assets from private or public github repositories'
author: 'Robin Raju'
inputs: inputs:
repository: repository:
description: "The source repository path. Expected format {owner}/{repo}" description: 'The source repository path. Expected format {owner}/{repo}'
default: ${{ github.repository }} default: ${{ github.repository }}
required: false required: false
latest: latest:
description: "A flag to choose between latest release and remaining releases" description:
default: "false" 'A flag to choose between latest release and remaining releases'
default: 'false'
required: false required: false
preRelease: preRelease:
description: "A flag to download from prerelease. It should be combined with latest flag" description:
default: "false" 'A flag to download from prerelease. It should be combined with latest
flag'
default: 'false'
required: false required: false
tag: tag:
description: "The github tag to download the release from" description: 'The github tag to download the release from'
default: "" default: ''
required: false required: false
fileName: fileName:
description: "Name of the file to download (use '*' to download all assets other than tarball or zipball)" description:
default: "" "Name of the file to download (use '*' to download all assets other than
tarball or zipball)"
default: ''
required: false required: false
tarBall: tarBall:
description: "Download tarball from assets" description: 'Download tarball from assets'
default: "false" default: 'false'
required: false required: false
zipBall: zipBall:
description: "Download zipball from assets" description: 'Download zipball from assets'
default: "false" default: 'false'
required: false required: false
out-file-path: out-file-path:
description: "Relative path under $GITHUB_WORKSPACE to place the downloaded files" description:
default: "." 'Relative path under $GITHUB_WORKSPACE to place the downloaded files'
default: '.'
required: true required: true
extract: extract:
description: "If the downloaded assets should be extracted to `out-file-path`. Supports tar, tar.gz and zip" description:
default: "false" 'If the downloaded assets should be extracted to `out-file-path`. Supports
tar, tar.gz and zip'
default: 'false'
required: false required: false
token: token:
description: "Github token to access private repos" description: 'Github token to access private repos'
default: ${{ github.token }} default: ${{ github.token }}
required: false required: false
github-api-url: github-api-url:
description: "The URL of the Github API, only use this input if you are using Github Enterprise" description:
default: "https://api.github.com" 'The URL of the Github API, only use this input if you are using Github
Enterprise'
default: 'https://api.github.com'
required: false required: false
releaseId: releaseId:
description: "The release id to download the file from" description: 'The release id to download the file from'
default: "" default: ''
required: false required: false
outputs: outputs:
tag_name: tag_name:
description: "The github tag used to download the release" description: 'The github tag used to download the release'
release_name: release_name:
description: "The release name / title" description: 'The release name / title'
downloaded_files: downloaded_files:
description: "The array of downloaded files, useful when using wildcard '*' to download multiple files." description:
"The array of downloaded files, useful when using wildcard '*' to download
multiple files."
runs: runs:
using: "node20" using: 'node20'
main: "dist/index.js" main: 'dist/index.js'
branding: branding:
icon: "download" icon: 'download'
color: "green" color: 'green'
Generated Vendored
+9223 -8171
View File
File diff suppressed because it is too large. Load diff
Generated Vendored
+144 -70
View File
@@ -69,6 +69,25 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE. IN THE SOFTWARE.
@isaacs/fs-minipass
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
balanced-match balanced-match
MIT MIT
(MIT) (MIT)
@@ -145,22 +164,70 @@ SOFTWARE.
chownr chownr
ISC BlueOak-1.0.0
The ISC License All packages under `src/` are licensed according to the terms in
their respective `LICENSE` or `LICENSE.md` files.
Copyright (c) Isaac Z. Schlueter and Contributors The remainder of this project is licensed under the Blue Oak
Model License, as follows:
Permission to use, copy, modify, and/or distribute this software for any -----
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # Blue Oak Model License
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR Version 1.0.0
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ## Purpose
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. This license gives everyone as much permission to work with
this software as possible, while protecting contributors
from liability.
## Acceptance
In order to receive this license, you must agree to its
rules. The rules of this license are both obligations
under that agreement and conditions to your license.
You must not do anything with this software that triggers
a rule that you cannot or will not follow.
## Copyright
Each contributor licenses you to do everything with this
software that would otherwise infringe that contributor's
copyright in it.
## Notices
You must ensure that everyone who gets a copy of
any part of this software from you, with or without
changes, also gets the text of this license or a link to
<https://blueoakcouncil.org/license/1.0.0>.
## Excuse
If anyone notifies you in writing that you have not
complied with [Notices](#notices), you can keep your
license by taking all practical steps to comply within 30
days after the notice. If you do not do so, your license
ends immediately.
## Patent
Each contributor licenses you to do everything with this
software that would otherwise infringe any patent claims
they can license or become able to license.
## Reliability
No contributor can revoke this license.
## No Liability
***As far as the law allows, this software comes as is,
without any warranty or condition, and no contributor
will be liable to anyone for any damages related to this
software or this license, under any kind of legal claim.***
define-data-property define-data-property
@@ -238,25 +305,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
fs-minipass
ISC
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
function-bind function-bind
MIT MIT
Copyright (c) 2013 Raynos. Copyright (c) 2013 Raynos.
@@ -475,9 +523,9 @@ Minizlib was created by Isaac Z. Schlueter.
It is a derivative work of the Node.js project. It is a derivative work of the Node.js project.
""" """
Copyright Isaac Z. Schlueter and Contributors Copyright (c) 2017-2023 Isaac Z. Schlueter and Contributors
Copyright Node.js contributors. All rights reserved. Copyright (c) 2017-2023 Node.js contributors. All rights reserved.
Copyright Joyent, Inc. and other Node contributors. All rights reserved. Copyright (c) 2017-2023 Joyent, Inc. and other Node contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
@@ -501,28 +549,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
mkdirp mkdirp
MIT MIT
Copyright James Halliday (mail@substack.net) and Isaac Z. Schlueter (i@izs.me)
This project is free software released under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
node-stream-zip node-stream-zip
MIT MIT
@@ -831,19 +857,67 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
yallist yallist
ISC BlueOak-1.0.0
The ISC License All packages under `src/` are licensed according to the terms in
their respective `LICENSE` or `LICENSE.md` files.
Copyright (c) Isaac Z. Schlueter and Contributors The remainder of this project is licensed under the Blue Oak
Model License, as follows:
Permission to use, copy, modify, and/or distribute this software for any -----
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # Blue Oak Model License
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR Version 1.0.0
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ## Purpose
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. This license gives everyone as much permission to work with
this software as possible, while protecting contributors
from liability.
## Acceptance
In order to receive this license, you must agree to its
rules. The rules of this license are both obligations
under that agreement and conditions to your license.
You must not do anything with this software that triggers
a rule that you cannot or will not follow.
## Copyright
Each contributor licenses you to do everything with this
software that would otherwise infringe that contributor's
copyright in it.
## Notices
You must ensure that everyone who gets a copy of
any part of this software from you, with or without
changes, also gets the text of this license or a link to
<https://blueoakcouncil.org/license/1.0.0>.
## Excuse
If anyone notifies you in writing that you have not
complied with [Notices](#notices), you can keep your
license by taking all practical steps to comply within 30
days after the notice. If you do not do so, your license
ends immediately.
## Patent
Each contributor licenses you to do everything with this
software that would otherwise infringe any patent claims
they can license or become able to license.
## Reliability
No contributor can revoke this license.
## No Liability
***As far as the law allows, this software comes as is,
without any warranty or condition, and no contributor
will be liable to anyone for any damages related to this
software or this license, under any kind of legal claim.***
-9
View File
@@ -1,9 +0,0 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ["js", "ts"],
testMatch: ["**/*.test.ts"],
transform: {
"^.+\\.ts$": "ts-jest"
},
verbose: true
}
+876 -459
View File
File diff suppressed because it is too large. Load diff
+53 -18
View File
@@ -1,18 +1,26 @@
{ {
"name": "release-downloader", "name": "release-downloader",
"version": "1.0.0", "version": "1.0.0",
"author": "Robin Raju",
"license": "MIT",
"private": true, "private": true,
"description": "Github action to download release assets", "description": "Github action to download release assets",
"main": "lib/main.js", "exports": {
".": "./dist/index.js"
},
"engines": {
"node": ">=20"
},
"scripts": { "scripts": {
"build": "tsc", "bundle": "npm run format:write && npm run package",
"format": "prettier --write **/*.ts", "ci-test": "npx jest",
"format-check": "prettier --check **/*.ts", "format:write": "npx prettier --write .",
"lint": "eslint src/**/*.ts", "format:check": "npx prettier --check .",
"package": "ncc build --license licenses.txt", "lint": "npx eslint . -c ./.github/linters/.eslintrc.yml",
"release": "npm run build && npm run package", "package": "npx ncc build src/main.ts -o dist --license licenses.txt",
"test": "jest --detectOpenHandles", "package:watch": "npm run package -- --watch",
"all": "npm run build && npm run format && npm run lint && npm run package && npm test" "test": "npx jest",
"all": "npm run format:write && npm run lint && npm run test && npm run package"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@@ -24,33 +32,60 @@
"setup", "setup",
"github release download" "github release download"
], ],
"author": "Robin Raju", "jest": {
"license": "MIT", "preset": "ts-jest",
"verbose": true,
"clearMocks": true,
"testEnvironment": "node",
"moduleFileExtensions": [
"js",
"ts"
],
"testMatch": [
"**/*.test.ts"
],
"testPathIgnorePatterns": [
"/node_modules/",
"/dist/"
],
"transform": {
"^.+\\.ts$": "ts-jest"
},
"coverageReporters": [
"json-summary",
"text",
"lcov"
],
"collectCoverage": true,
"collectCoverageFrom": [
"./src/**"
]
},
"dependencies": { "dependencies": {
"@actions/core": "^1.10.1", "@actions/core": "^1.10.1",
"@actions/io": "^1.1.3", "@actions/io": "^1.1.3",
"minimatch": "^9.0.4", "minimatch": "^9.0.4",
"node-stream-zip": "^1.15.0", "node-stream-zip": "^1.15.0",
"tar": "^6.2.1", "tar": "^7.0.1",
"typed-rest-client": "^1.8.11" "typed-rest-client": "^1.8.11"
}, },
"devDependencies": { "devDependencies": {
"@jest/globals": "^29.7.0",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/node": "^20.12.7", "@types/node": "^20.12.7",
"@types/tar": "^6.1.12", "@types/tar": "^6.1.12",
"@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/eslint-plugin": "^7.7.1",
"@typescript-eslint/parser": "^6.21.0", "@typescript-eslint/parser": "^7.7.1",
"@vercel/ncc": "^0.38.1", "@vercel/ncc": "^0.38.1",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-plugin-github": "^4.10.2", "eslint-plugin-github": "^4.10.2",
"eslint-plugin-jest": "^27.9.0", "eslint-plugin-jest": "^28.2.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-circus": "^29.7.0",
"js-yaml": "^4.1.0",
"nock": "^13.5.4", "nock": "^13.5.4",
"prettier": "3.2.5", "prettier": "3.2.5",
"prettier-eslint": "^16.3.0",
"ts-jest": "^29.1.2", "ts-jest": "^29.1.2",
"typescript": "5.3.3" "typescript": "5.4.5"
} }
} }
+1 -1
View File
@@ -6,7 +6,7 @@ interface GhAsset {
export interface GithubRelease { export interface GithubRelease {
name: string name: string
id: number id: number
tag_name: String tag_name: string
prerelease: boolean prerelease: boolean
assets: GhAsset[] assets: GhAsset[]
tarball_url: string tarball_url: string
+16 -16
View File
@@ -1,9 +1,9 @@
import * as core from "@actions/core" import * as core from '@actions/core'
import * as path from "path" import * as path from 'path'
import {IReleaseDownloadSettings} from "./download-settings" import { IReleaseDownloadSettings } from './download-settings'
function validateRepositoryPath(repositoryPath: string): void { function validateRepositoryPath(repositoryPath: string): void {
const repoParts = repositoryPath.split("/") const repoParts = repositoryPath.split('/')
if (repoParts.length !== 2 || !repoParts[0] || !repoParts[1]) { if (repoParts.length !== 2 || !repoParts[0] || !repoParts[1]) {
throw new Error( throw new Error(
`Invalid repository '${repositoryPath}'. Expected format {owner}/{repo}.` `Invalid repository '${repositoryPath}'. Expected format {owner}/{repo}.`
@@ -24,19 +24,19 @@ function validateReleaseVersion(
} }
export function getInputs(): IReleaseDownloadSettings { export function getInputs(): IReleaseDownloadSettings {
let githubWorkspacePath = process.env["GITHUB_WORKSPACE"] let githubWorkspacePath = process.env['GITHUB_WORKSPACE']
if (!githubWorkspacePath) { if (!githubWorkspacePath) {
throw new Error("$GITHUB_WORKSPACE not defined") throw new Error('$GITHUB_WORKSPACE not defined')
} }
githubWorkspacePath = path.resolve(githubWorkspacePath) githubWorkspacePath = path.resolve(githubWorkspacePath)
const repositoryPath = core.getInput("repository") const repositoryPath = core.getInput('repository')
validateRepositoryPath(repositoryPath) validateRepositoryPath(repositoryPath)
const latestFlag = core.getBooleanInput("latest") const latestFlag = core.getBooleanInput('latest')
const preReleaseFlag = core.getBooleanInput("preRelease") const preReleaseFlag = core.getBooleanInput('preRelease')
const ghTag = core.getInput("tag") const ghTag = core.getInput('tag')
const releaseId = core.getInput("releaseId") const releaseId = core.getInput('releaseId')
validateReleaseVersion(latestFlag, ghTag, releaseId) validateReleaseVersion(latestFlag, ghTag, releaseId)
@@ -46,13 +46,13 @@ export function getInputs(): IReleaseDownloadSettings {
preRelease: preReleaseFlag, preRelease: preReleaseFlag,
tag: ghTag, tag: ghTag,
id: releaseId, id: releaseId,
fileName: core.getInput("fileName"), fileName: core.getInput('fileName'),
tarBall: core.getBooleanInput("tarBall"), tarBall: core.getBooleanInput('tarBall'),
zipBall: core.getBooleanInput("zipBall"), zipBall: core.getBooleanInput('zipBall'),
extractAssets: core.getBooleanInput("extract"), extractAssets: core.getBooleanInput('extract'),
outFilePath: path.resolve( outFilePath: path.resolve(
githubWorkspacePath, githubWorkspacePath,
core.getInput("out-file-path") || "." core.getInput('out-file-path') || '.'
) )
} }
} }
+9 -9
View File
@@ -1,22 +1,22 @@
import * as core from "@actions/core" import * as core from '@actions/core'
import * as handlers from "typed-rest-client/Handlers" import * as handlers from 'typed-rest-client/Handlers'
import * as inputHelper from "./input-helper" import * as inputHelper from './input-helper'
import * as thc from "typed-rest-client/HttpClient" import * as thc from 'typed-rest-client/HttpClient'
import {ReleaseDownloader} from "./release-downloader" import { ReleaseDownloader } from './release-downloader'
import {extract} from "./unarchive" import { extract } from './unarchive'
async function run(): Promise<void> { async function run(): Promise<void> {
try { try {
const downloadSettings = inputHelper.getInputs() const downloadSettings = inputHelper.getInputs()
const authToken = core.getInput("token") const authToken = core.getInput('token')
const githubApiUrl = core.getInput("github-api-url") const githubApiUrl = core.getInput('github-api-url')
const credentialHandler = new handlers.BearerCredentialHandler( const credentialHandler = new handlers.BearerCredentialHandler(
authToken, authToken,
false false
) )
const httpClient: thc.HttpClient = new thc.HttpClient("gh-api-client", [ const httpClient: thc.HttpClient = new thc.HttpClient('gh-api-client', [
credentialHandler credentialHandler
]) ])
+30 -30
View File
@@ -1,14 +1,14 @@
import * as core from "@actions/core" import * as core from '@actions/core'
import * as fs from "fs" import * as fs from 'fs'
import * as io from "@actions/io" import * as io from '@actions/io'
import * as path from "path" import * as path from 'path'
import * as thc from "typed-rest-client/HttpClient" import * as thc from 'typed-rest-client/HttpClient'
import {minimatch} from "minimatch" import { minimatch } from 'minimatch'
import {DownloadMetaData, GithubRelease} from "./gh-api" import { DownloadMetaData, GithubRelease } from './gh-api'
import {IHeaders, IHttpClientResponse} from "typed-rest-client/Interfaces" import { IHeaders, IHttpClientResponse } from 'typed-rest-client/Interfaces'
import {IReleaseDownloadSettings} from "./download-settings" import { IReleaseDownloadSettings } from './download-settings'
export class ReleaseDownloader { export class ReleaseDownloader {
private httpClient: thc.HttpClient private httpClient: thc.HttpClient
@@ -30,19 +30,19 @@ export class ReleaseDownloader {
downloadSettings.sourceRepoPath, downloadSettings.sourceRepoPath,
downloadSettings.preRelease downloadSettings.preRelease
) )
} else if (downloadSettings.tag !== "") { } else if (downloadSettings.tag !== '') {
ghRelease = await this.getReleaseByTag( ghRelease = await this.getReleaseByTag(
downloadSettings.sourceRepoPath, downloadSettings.sourceRepoPath,
downloadSettings.tag downloadSettings.tag
) )
} else if (downloadSettings.id !== "") { } else if (downloadSettings.id !== '') {
ghRelease = await this.getReleaseById( ghRelease = await this.getReleaseById(
downloadSettings.sourceRepoPath, downloadSettings.sourceRepoPath,
downloadSettings.id downloadSettings.id
) )
} else { } else {
throw new Error( throw new Error(
"Config error: Please input a valid tag or release ID, or specify `latest`" 'Config error: Please input a valid tag or release ID, or specify `latest`'
) )
} }
@@ -57,9 +57,9 @@ export class ReleaseDownloader {
) )
// Set the output variables for use by other actions // Set the output variables for use by other actions
core.setOutput("tag_name", ghRelease.tag_name) core.setOutput('tag_name', ghRelease.tag_name)
core.setOutput("release_name", ghRelease.name) core.setOutput('release_name', ghRelease.name)
core.setOutput("downloaded_files", result) core.setOutput('downloaded_files', result)
return result return result
} }
@@ -74,7 +74,7 @@ export class ReleaseDownloader {
): Promise<GithubRelease> { ): Promise<GithubRelease> {
core.info(`Fetching latest release for repo ${repoPath}`) core.info(`Fetching latest release for repo ${repoPath}`)
const headers: IHeaders = {Accept: "application/vnd.github.v3+json"} const headers: IHeaders = { Accept: 'application/vnd.github.v3+json' }
let response: IHttpClientResponse let response: IHttpClientResponse
if (!preRelease) { if (!preRelease) {
@@ -112,7 +112,7 @@ export class ReleaseDownloader {
release = latestPreRelease release = latestPreRelease
core.info(`Found latest pre-release version: ${release.tag_name}`) core.info(`Found latest pre-release version: ${release.tag_name}`)
} else { } else {
throw new Error("No prereleases found!") throw new Error('No prereleases found!')
} }
} }
@@ -130,11 +130,11 @@ export class ReleaseDownloader {
): Promise<GithubRelease> { ): Promise<GithubRelease> {
core.info(`Fetching release ${tag} from repo ${repoPath}`) core.info(`Fetching release ${tag} from repo ${repoPath}`)
if (tag === "") { if (tag === '') {
throw new Error("Config error: Please input a valid tag") throw new Error('Config error: Please input a valid tag')
} }
const headers: IHeaders = {Accept: "application/vnd.github.v3+json"} const headers: IHeaders = { Accept: 'application/vnd.github.v3+json' }
const response = await this.httpClient.get( const response = await this.httpClient.get(
`${this.apiRoot}/repos/${repoPath}/releases/tags/${tag}`, `${this.apiRoot}/repos/${repoPath}/releases/tags/${tag}`,
@@ -166,11 +166,11 @@ export class ReleaseDownloader {
): Promise<GithubRelease> { ): Promise<GithubRelease> {
core.info(`Fetching release id:${id} from repo ${repoPath}`) core.info(`Fetching release id:${id} from repo ${repoPath}`)
if (id === "") { if (id === '') {
throw new Error("Config error: Please input a valid release ID") throw new Error('Config error: Please input a valid release ID')
} }
const headers: IHeaders = {Accept: "application/vnd.github.v3+json"} const headers: IHeaders = { Accept: 'application/vnd.github.v3+json' }
const response = await this.httpClient.get( const response = await this.httpClient.get(
`${this.apiRoot}/repos/${repoPath}/releases/${id}`, `${this.apiRoot}/repos/${repoPath}/releases/${id}`,
@@ -207,7 +207,7 @@ export class ReleaseDownloader {
const dData: DownloadMetaData = { const dData: DownloadMetaData = {
fileName: asset.name, fileName: asset.name,
url: asset["url"], url: asset['url'],
isTarBallOrZipBall: false isTarBallOrZipBall: false
} }
downloads.push(dData) downloads.push(dData)
@@ -224,7 +224,7 @@ export class ReleaseDownloader {
} }
if (downloadSettings.tarBall) { if (downloadSettings.tarBall) {
const repoName = downloadSettings.sourceRepoPath.split("/")[1] const repoName = downloadSettings.sourceRepoPath.split('/')[1]
downloads.push({ downloads.push({
fileName: `${repoName}-${ghRelease.tag_name}.tar.gz`, fileName: `${repoName}-${ghRelease.tag_name}.tar.gz`,
url: ghRelease.tarball_url, url: ghRelease.tarball_url,
@@ -233,7 +233,7 @@ export class ReleaseDownloader {
} }
if (downloadSettings.zipBall) { if (downloadSettings.zipBall) {
const repoName = downloadSettings.sourceRepoPath.split("/")[1] const repoName = downloadSettings.sourceRepoPath.split('/')[1]
downloads.push({ downloads.push({
fileName: `${repoName}-${ghRelease.tag_name}.zip`, fileName: `${repoName}-${ghRelease.tag_name}.zip`,
url: ghRelease.zipball_url, url: ghRelease.zipball_url,
@@ -274,11 +274,11 @@ export class ReleaseDownloader {
outputPath: string outputPath: string
): Promise<string> { ): Promise<string> {
const headers: IHeaders = { const headers: IHeaders = {
Accept: "application/octet-stream" Accept: 'application/octet-stream'
} }
if (asset.isTarBallOrZipBall) { if (asset.isTarBallOrZipBall) {
headers["Accept"] = "*/*" headers['Accept'] = '*/*'
} }
core.info(`Downloading file: ${asset.fileName} to: ${outputPath}`) core.info(`Downloading file: ${asset.fileName} to: ${outputPath}`)
@@ -303,10 +303,10 @@ export class ReleaseDownloader {
const fileStream: fs.WriteStream = fs.createWriteStream(outFilePath) const fileStream: fs.WriteStream = fs.createWriteStream(outFilePath)
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fileStream.on("error", err => reject(err)) fileStream.on('error', err => reject(err))
const outStream = httpClientResponse.message.pipe(fileStream) const outStream = httpClientResponse.message.pipe(fileStream)
outStream.on("close", () => { outStream.on('close', () => {
resolve(outFilePath) resolve(outFilePath)
}) })
}) })
+9 -9
View File
@@ -1,15 +1,15 @@
import * as core from "@actions/core" import * as core from '@actions/core'
import * as fs from "fs" import * as fs from 'fs'
import * as path from "path" import * as path from 'path'
import * as tar from "tar" import * as tar from 'tar'
import * as StreamZip from "node-stream-zip" import * as StreamZip from 'node-stream-zip'
export const extract = async ( export const extract = async (
filePath: string, filePath: string,
destDir: string destDir: string
): Promise<void> => { ): Promise<void> => {
const isTarGz = filePath.endsWith(".tar.gz") || filePath.endsWith(".tar") const isTarGz = filePath.endsWith('.tar.gz') || filePath.endsWith('.tar')
const isZip = filePath.endsWith(".zip") const isZip = filePath.endsWith('.zip')
const filename = path.basename(filePath) const filename = path.basename(filePath)
if (!isTarGz && !isZip) { if (!isTarGz && !isZip) {
@@ -21,7 +21,7 @@ export const extract = async (
// Create the destination directory if it doesn't already exist // Create the destination directory if it doesn't already exist
if (!fs.existsSync(destDir)) { if (!fs.existsSync(destDir)) {
fs.mkdirSync(destDir, {recursive: true}) fs.mkdirSync(destDir, { recursive: true })
} }
// Extract the file to the destination directory // Extract the file to the destination directory
@@ -32,7 +32,7 @@ export const extract = async (
}) })
} }
if (isZip) { if (isZip) {
const zip = new StreamZip.async({file: filePath}) const zip = new StreamZip.async({ file: filePath })
await zip.extract(null, destDir) await zip.extract(null, destDir)
await zip.close() await zip.close()
} }
+16 -9
View File
@@ -1,12 +1,19 @@
{ {
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": { "compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ "target": "ES2022",
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ "module": "NodeNext",
"outDir": "./lib", /* Redirect output structure to the directory. */ "rootDir": "./src",
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ "moduleResolution": "NodeNext",
"strict": true, /* Enable all strict type-checking options. */ "baseUrl": "./",
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ "sourceMap": true,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ "outDir": "./dist",
"noImplicitAny": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"newLine": "lf"
}, },
"exclude": ["node_modules", "**/*.test.ts"] "exclude": ["./dist", "./node_modules", "./__tests__", "./coverage"]
} }