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/
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: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**Describe the bug** 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 '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Expected behavior** A clear and concise description of what you expected to
happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Screenshots** If applicable, add screenshots to help explain your problem.
**Action Environment (please complete the following information):**
- OS: [e.g. ubuntu-latest]
**Additional context**
Add any other context about the problem here.
- OS: [e.g. ubuntu-latest]
**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: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Is your feature request related to a problem? Please describe.** A clear and
concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe the solution you'd like** A clear and concise description of what you
want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Describe alternatives you've considered** A clear and concise description of
any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
**Additional context** Add any other context or screenshots about the feature
request here.
+22 -11
View File
@@ -1,15 +1,26 @@
# Enable dependabot on this repo to update dependencies periodically.
version: 2
updates:
# Enable version updates for npm
- package-ecosystem: "npm"
# Look for `package.json` and `lock` files in the `root` directory
directory: "/"
# Check the npm registry for updates every day (weekdays)
- package-ecosystem: github-actions
directory: /
schedule:
interval: "weekly"
# Enable version updates for github actions
- package-ecosystem: "github-actions"
directory: "/"
interval: weekly
groups:
actions-minor:
update-types:
- minor
- patch
- package-ecosystem: npm
directory: /
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:
# Trigger manually
workflow_dispatch:
pull_request:
push:
tags:
- "*"
- '*'
branches:
- main
@@ -18,96 +18,95 @@ jobs:
- macos-latest
- windows-latest
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Checkout Repo
uses: actions/checkout@v4
- name: Setup node and cache dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Setup node and cache dependencies
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Build and test
shell: bash
run: |
npm ci
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: Build and test
shell: bash
run: |
npm ci
npm run all
- name: Download tarBall & zipBall only
uses: ./
with:
repository: "robinraju/probable-potato"
tag: "1.0.2"
tarBall: true
zipBall: true
out-file-path: "./public-download"
- 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 public-download
- 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
shell: bash
run: ls -lrth test-downloads
- name: List downloaded files
shell: bash
run: ls -lrth prerelease-downloads
- name: Download tarBall & zipBall only
uses: ./
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
uses: ./
id: download-private
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
shell: bash
run: ls -lrth public-download
- name: List downloaded files from private repo
shell: bash
run: ls -lrth downloader-test
- 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: 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
- name: List downloaded files
shell: bash
run: ls -lrth prerelease-downloads
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
- name: Test download from a private repo
uses: ./
id: download-private
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:"
echo ${{steps.download-public.outputs.downloaded_files}}
- name: List downloaded files from private repo
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:
- name: Automatic merge PR by dependabot
conditions:
- "author=dependabot[bot]"
- "status-success=build (ubuntu-latest)"
- "status-success=build (macos-latest)"
- "status-success=build (windows-latest)"
- 'author=dependabot[bot]'
- 'status-success=build (ubuntu-latest)'
- 'status-success=build (macos-latest)'
- 'status-success=build (windows-latest)'
actions:
merge:
method: squash
delete_head_branch:
delete_head_branch:
force: true
+8 -3
View File
@@ -3,9 +3,14 @@
"tabWidth": 2,
"useTabs": false,
"semi": false,
"singleQuote": false,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"trailingComma": "none",
"bracketSpacing": false,
"bracketSpacing": true,
"bracketSameLine": true,
"arrowParens": "avoid",
"parser": "typescript"
"proseWrap": "always",
"htmlWhitespaceSensitivity": "css",
"endOfLine": "lf"
}
+34 -22
View File
@@ -5,19 +5,22 @@
- Node > v12.x
- npm
Install the dependencies
Install dependencies
```bash
$ npm install
npm install
```
Build the typescript and package it for distribution
Build typescript and package it for distribution
```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
$ npm test
npm test
PASS __tests__/main.test.ts
✓ run download (1207ms)
@@ -35,22 +38,25 @@ Ran all test suites.
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
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
import * as core from '@actions/core';
...
async function run() {
try {
try {
...
}
}
catch (error) {
core.setFailed(error.message);
}
@@ -59,13 +65,16 @@ async function 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
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:
```bash
$ npm run package
$ git add dist
@@ -73,21 +82,24 @@ $ git commit -a -m "prod dependencies"
$ 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
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
uses: ./
with:
repository: "user/repo"
tag: "1.0.0"
fileName: "foo.zip"
out-file-path: "."
with:
repository: 'user/repo'
tag: '1.0.0'
fileName: 'foo.zip'
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)
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
```yaml
- uses: robinraju/release-downloader@v1.10
with:
with:
# The source repository path.
# Expected format {owner}/{repo}
# Default: ${{ github.repository }}
repository: ""
repository: ''
# A flag to set the download target as latest release
# The default value is 'false'
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.
# The default value is 'false'
preRelease: true
# The github tag. e.g: v1.0.1
# Download assets from a specific tag/version
tag: ""
# The release id to download files from
releaseId: ""
tag: ''
# The release id to download files from
releaseId: ''
# The name of the file to download.
# Use this field only to specify filenames other than tarball or zipball, if any.
# Supports wildcard pattern (eg: '*', '*.deb', '*.zip' etc..)
fileName: ""
fileName: ''
# Download the attached tarball (*.tar.gz)
tarBall: true
# Download the attached zipball (*.zip)
zipBall: true
# Relative path under $GITHUB_WORKSPACE to place the downloaded file(s)
# It will create the target directory automatically if not present
# 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
# 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
# https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets
# eg: token: ${{ secrets.MY_TOKEN }}
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: ""
github-api-url: ''
```
#### Output variables
### Output variables
- `tag_name` it outputs the tag used to download a release.
> 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
> It can ce used as follows
> ```
> ${{steps.<step-id>.outputs.release_name}}
>```
It can be used as follows
```sh
${{steps.<step-id>.outputs.release_name}}
```
- `downloaded_files` it outputs an array of downloaded files
> It can be used as follows
>
> `${{ fromJson(steps.<step-id>.outputs.downloaded_files)[0] }}`
It can be used as follows
```sh
${{ fromJson(steps.<step-id>.outputs.downloaded_files)[0] }}
```
## Scenarios
### Download asset from the latest release in the current repository
```yaml
- uses: robinraju/release-downloader@v1.10
with:
latest: true
fileName: "foo.zip"
fileName: 'foo.zip'
```
### Download asset from a specific release version.
### Download asset from a specific release version
```yaml
- uses: robinraju/release-downloader@v1.10
with:
repository: "owner/repo"
tag: "v1.0.0"
fileName: "foo.zip"
repository: 'owner/repo'
tag: 'v1.0.0'
fileName: 'foo.zip'
```
### Download tarball and zipball
```yaml
- uses: robinraju/release-downloader@v1.10
with:
repository: "owner/repo"
repository: 'owner/repo'
latest: true
tarBall: 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
```yaml
- uses: robinraju/release-downloader@v1.10
with:
repository: "owner/repo"
repository: 'owner/repo'
latest: true
fileName: "foo.zip"
fileName: 'foo.zip'
tarBall: true
zipBall: true
```
@@ -136,9 +140,9 @@ A Github Action to download assets from github release. It can download specifie
```yaml
- uses: robinraju/release-downloader@v1.10
with:
repository: "owner/repo"
repository: 'owner/repo'
latest: true
fileName: "*"
fileName: '*'
```
### Download assets using wildcard pattern
@@ -146,9 +150,9 @@ A Github Action to download assets from github release. It can download specifie
```yaml
- uses: robinraju/release-downloader@v1.10
with:
repository: "owner/repo"
repository: 'owner/repo'
latest: true
fileName: "*.deb"
fileName: '*.deb'
```
### Download a release using its id
@@ -156,8 +160,8 @@ A Github Action to download assets from github release. It can download specifie
```yaml
- uses: robinraju/release-downloader@v1.10
with:
releaseId: "123123"
fileName: "foo.zip"
releaseId: '123123'
fileName: 'foo.zip'
```
### Download and extracts archives
@@ -165,7 +169,7 @@ A Github Action to download assets from github release. It can download specifie
```yaml
- uses: robinraju/release-downloader@v1.10
with:
fileName: "foo.zip"
fileName: 'foo.zip'
latest: true
extract: true
```
@@ -175,8 +179,8 @@ A Github Action to download assets from github release. It can download specifie
```yaml
- uses: robinraju/release-downloader@v1.10
with:
repository: "owner/repo"
fileName: "foo.zip"
repository: 'owner/repo'
fileName: 'foo.zip'
latest: true
preRelease: true
```
+166 -164
View File
@@ -1,127 +1,127 @@
import * as fs from "fs"
import * as path from "path"
import * as handlers from "typed-rest-client/Handlers"
import * as io from "@actions/io"
import * as thc from "typed-rest-client/HttpClient"
import * as fs from 'fs'
import * as path from 'path'
import * as handlers from 'typed-rest-client/Handlers'
import * as io from '@actions/io'
import * as thc from 'typed-rest-client/HttpClient'
import {IReleaseDownloadSettings} from "../src/download-settings"
import {ReleaseDownloader} from "../src/release-downloader"
import nock from "nock"
import {extract} from "../src/unarchive"
import { IReleaseDownloadSettings } from '../src/download-settings'
import { ReleaseDownloader } from '../src/release-downloader'
import nock from 'nock'
import { extract } from '../src/unarchive'
let downloader: ReleaseDownloader
let httpClent: thc.HttpClient
const outputFilePath = "./test-output"
const outputFilePath = './test-output'
beforeEach(() => {
const githubtoken = process.env.REPO_TOKEN || ""
const githubApiUrl = "https://api.github.com"
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])
httpClent = new thc.HttpClient('gh-api-client', [credentialHandler])
downloader = new ReleaseDownloader(httpClent, githubApiUrl)
nock("https://api.github.com")
.get("/repos/robinraju/probable-potato/releases/latest")
.reply(200, readFromFile("1-release-latest.json"))
nock('https://api.github.com')
.get('/repos/robinraju/probable-potato/releases/latest')
.reply(200, readFromFile('1-release-latest.json'))
nock("https://api.github.com")
.get("/repos/robinraju/probable-potato/releases/68092191")
.reply(200, readFromFile("1-release-latest.json"))
nock('https://api.github.com')
.get('/repos/robinraju/probable-potato/releases/68092191')
.reply(200, readFromFile('1-release-latest.json'))
nock("https://api.github.com")
.get("/repos/robinraju/foo-app/releases/tags/1.0.0")
.reply(200, readFromFile("3-empty-assets.json"))
nock('https://api.github.com')
.get('/repos/robinraju/foo-app/releases/tags/1.0.0')
.reply(200, readFromFile('3-empty-assets.json'))
nock("https://api.github.com", {
reqheaders: {accept: "application/octet-stream"}
nock('https://api.github.com', {
reqheaders: { accept: 'application/octet-stream' }
})
.get("/repos/robinraju/probable-potato/releases/assets/66946546")
.replyWithFile(200, __dirname + "/resource/assets/test-1.txt")
.get('/repos/robinraju/probable-potato/releases/assets/66946546')
.replyWithFile(200, `${__dirname}/resource/assets/test-1.txt`)
nock("https://api.github.com", {
reqheaders: {accept: "application/octet-stream"}
nock('https://api.github.com', {
reqheaders: { accept: 'application/octet-stream' }
})
.get("/repos/robinraju/probable-potato/releases/assets/66946547")
.replyWithFile(200, __dirname + "/resource/assets/test-2.txt")
.get('/repos/robinraju/probable-potato/releases/assets/66946547')
.replyWithFile(200, `${__dirname}/resource/assets/test-2.txt`)
nock("https://api.github.com", {
reqheaders: {accept: "application/octet-stream"}
nock('https://api.github.com', {
reqheaders: { accept: 'application/octet-stream' }
})
.get("/repos/robinraju/probable-potato/releases/assets/66946548")
.replyWithFile(200, __dirname + "/resource/assets/3-test.txt")
.get('/repos/robinraju/probable-potato/releases/assets/66946548')
.replyWithFile(200, `${__dirname}/resource/assets/3-test.txt`)
nock("https://api.github.com", {
reqheaders: {accept: "application/octet-stream"}
nock('https://api.github.com', {
reqheaders: { accept: 'application/octet-stream' }
})
.get("/repos/robinraju/probable-potato/releases/assets/66946549")
.replyWithFile(200, __dirname + "/resource/assets/downloader-test.pdf")
.get('/repos/robinraju/probable-potato/releases/assets/66946549')
.replyWithFile(200, `${__dirname}/resource/assets/downloader-test.pdf`)
nock("https://api.github.com", {
reqheaders: {accept: "application/octet-stream"}
nock('https://api.github.com', {
reqheaders: { accept: 'application/octet-stream' }
})
.get("/repos/robinraju/probable-potato/releases/assets/66946550")
.replyWithFile(200, __dirname + "/resource/assets/lorem-ipsum.pdf")
.get('/repos/robinraju/probable-potato/releases/assets/66946550')
.replyWithFile(200, `${__dirname}/resource/assets/lorem-ipsum.pdf`)
nock("https://api.github.com", {
reqheaders: {accept: "application/octet-stream"}
nock('https://api.github.com', {
reqheaders: { accept: 'application/octet-stream' }
})
.get("/repos/robinraju/probable-potato/releases/assets/66946552")
.replyWithFile(200, __dirname + "/resource/assets/archive-example.zip")
.get('/repos/robinraju/probable-potato/releases/assets/66946552')
.replyWithFile(200, `${__dirname}/resource/assets/archive-example.zip`)
nock("https://api.github.com", {
reqheaders: {accept: "application/octet-stream"}
nock('https://api.github.com', {
reqheaders: { accept: 'application/octet-stream' }
})
.get("/repos/robinraju/probable-potato/releases/assets/66946551")
.replyWithFile(200, __dirname + "/resource/assets/file_example.csv")
.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')
.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"}
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")
.get('/repos/my-enterprise/test-repo/releases/assets/66946546')
.replyWithFile(200, `${__dirname}/resource/assets/test-1.txt`)
nock("https://api.github.com/")
.get("/repos/robinraju/slick-pg/releases")
.reply(200, readFromFile("4-with-prerelease.json"))
nock('https://api.github.com/')
.get('/repos/robinraju/slick-pg/releases')
.reply(200, readFromFile('4-with-prerelease.json'))
nock("https://api.github.com", {
reqheaders: {accept: "application/octet-stream"}
nock('https://api.github.com', {
reqheaders: { accept: 'application/octet-stream' }
})
.get("/repos/robinraju/slick-pg/releases/assets/66946546")
.replyWithFile(200, __dirname + "/resource/assets/pre-release.txt")
.get('/repos/robinraju/slick-pg/releases/assets/66946546')
.replyWithFile(200, `${__dirname}/resource/assets/pre-release.txt`)
nock("https://api.github.com/")
.get("/repos/foo/slick-pg/releases")
.reply(200, readFromFile("5-without-prerelease.json"))
nock('https://api.github.com/')
.get('/repos/foo/slick-pg/releases')
.reply(200, readFromFile('5-without-prerelease.json'))
nock("https://api.github.com")
.get("/repos/robinraju/tar-zip-ball-only-repo/releases/latest")
.reply(200, readFromFile("6-tar-zip-ball-only-repo.json"))
nock('https://api.github.com')
.get('/repos/robinraju/tar-zip-ball-only-repo/releases/latest')
.reply(200, readFromFile('6-tar-zip-ball-only-repo.json'))
nock("https://api.github.com", {
reqheaders: {accept: "*/*"}
nock('https://api.github.com', {
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(
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", {
reqheaders: {accept: "*/*"}
nock('https://api.github.com', {
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(
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 {
const fileContents = fs.readFileSync(`${__dirname}/resource/${fileName}`, {
encoding: "utf-8"
encoding: 'utf-8'
})
return normalizeLineEndings(fileContents)
}
function normalizeLineEndings(str: string): string {
// 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 = {
sourceRepoPath: "robinraju/probable-potato",
sourceRepoPath: 'robinraju/probable-potato',
isLatest: true,
preRelease: false,
tag: "",
id: "",
fileName: "*",
tag: '',
id: '',
fileName: '*',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -158,14 +158,14 @@ test("Download all files from public repo", async () => {
expect(result.length).toBe(7)
}, 10000)
test("Download single file from public repo", async () => {
test('Download single file from public repo', async () => {
const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato",
sourceRepoPath: 'robinraju/probable-potato',
isLatest: true,
preRelease: false,
tag: "",
id: "",
fileName: "test-1.txt",
tag: '',
id: '',
fileName: 'test-1.txt',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -175,14 +175,14 @@ test("Download single file from public repo", async () => {
expect(result.length).toBe(1)
}, 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 = {
sourceRepoPath: "robinraju/probable-potato",
sourceRepoPath: 'robinraju/probable-potato',
isLatest: true,
preRelease: false,
tag: "",
id: "",
fileName: "missing-file.txt",
tag: '',
id: '',
fileName: 'missing-file.txt',
tarBall: false,
zipBall: 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)
await expect(result).rejects.toThrow(
"Asset with name missing-file.txt not found!"
'Asset with name missing-file.txt not found!'
)
}, 10000)
test("Fail loudly if release is not identified", async () => {
test('Fail loudly if release is not identified', async () => {
const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato",
sourceRepoPath: 'robinraju/probable-potato',
isLatest: false,
preRelease: false,
tag: "",
id: "",
fileName: "missing-file.txt",
tag: '',
id: '',
fileName: 'missing-file.txt',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -209,18 +209,18 @@ test("Fail loudly if release is not identified", async () => {
}
const result = downloader.download(downloadSettings)
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)
test("Download files with wildcard from public repo", async () => {
test('Download files with wildcard from public repo', async () => {
const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato",
sourceRepoPath: 'robinraju/probable-potato',
isLatest: true,
preRelease: false,
tag: "",
id: "",
fileName: "test-*.txt",
tag: '',
id: '',
fileName: 'test-*.txt',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -230,14 +230,14 @@ test("Download files with wildcard from public repo", async () => {
expect(result.length).toBe(2)
}, 10000)
test("Download single file with wildcard from public repo", async () => {
test('Download single file with wildcard from public repo', async () => {
const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato",
sourceRepoPath: 'robinraju/probable-potato',
isLatest: true,
preRelease: false,
tag: "",
id: "",
fileName: "3-*.txt",
tag: '',
id: '',
fileName: '3-*.txt',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -247,14 +247,14 @@ test("Download single file with wildcard from public repo", async () => {
expect(result.length).toBe(1)
}, 10000)
test("Download multiple pdf files with wildcard filename", async () => {
test('Download multiple pdf files with wildcard filename', async () => {
const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato",
sourceRepoPath: 'robinraju/probable-potato',
isLatest: true,
preRelease: false,
tag: "",
id: "",
fileName: "*.pdf",
tag: '',
id: '',
fileName: '*.pdf',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -264,14 +264,14 @@ test("Download multiple pdf files with wildcard filename", async () => {
expect(result.length).toBe(2)
}, 10000)
test("Download a csv file with wildcard filename", async () => {
test('Download a csv file with wildcard filename', async () => {
const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato",
sourceRepoPath: 'robinraju/probable-potato',
isLatest: true,
preRelease: false,
tag: "",
id: "",
fileName: "*.csv",
tag: '',
id: '',
fileName: '*.csv',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -281,16 +281,16 @@ test("Download a csv file with wildcard filename", async () => {
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")
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",
sourceRepoPath: 'my-enterprise/test-repo',
isLatest: true,
preRelease: false,
tag: "",
id: "",
fileName: "test-1.txt",
tag: '',
id: '',
fileName: 'test-1.txt',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -300,14 +300,14 @@ test("Download file from Github Enterprise server", async () => {
expect(result.length).toBe(1)
}, 10000)
test("Download file from release identified by ID", async () => {
test('Download file from release identified by ID', async () => {
const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato",
sourceRepoPath: 'robinraju/probable-potato',
isLatest: false,
preRelease: false,
tag: "",
id: "68092191",
fileName: "test-2.txt",
tag: '',
id: '68092191',
fileName: 'test-2.txt',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -317,14 +317,14 @@ test("Download file from release identified by ID", async () => {
expect(result.length).toBe(1)
}, 10000)
test("Download all archive files from public repo", async () => {
test('Download all archive files from public repo', async () => {
const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/probable-potato",
sourceRepoPath: 'robinraju/probable-potato',
isLatest: true,
preRelease: false,
tag: "",
id: "",
fileName: "*.zip",
tag: '',
id: '',
fileName: '*.zip',
tarBall: false,
zipBall: false,
extractAssets: true,
@@ -339,29 +339,31 @@ test("Download all archive files from public repo", async () => {
expect(result.length).toBe(1)
expect(
fs.existsSync(path.join(downloadSettings.outFilePath, "test-3.txt"))
fs.existsSync(path.join(downloadSettings.outFilePath, 'test-3.txt'))
).toBe(true)
const extractedFilePath = path.join(
downloadSettings.outFilePath,
"test-4.txt"
'test-4.txt'
)
expect(fs.existsSync(extractedFilePath)).toBe(true)
const actualContent = fs.readFileSync(extractedFilePath, {encoding: "utf-8"})
const expectedContent = readFromFile("assets/archive-example-test-4.txt")
const actualContent = fs.readFileSync(extractedFilePath, {
encoding: 'utf-8'
})
const expectedContent = readFromFile('assets/archive-example-test-4.txt')
expect(normalizeLineEndings(actualContent)).toBe(expectedContent)
}, 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 = {
sourceRepoPath: "robinraju/foo-app",
sourceRepoPath: 'robinraju/foo-app',
isLatest: false,
preRelease: false,
tag: "1.0.0",
id: "",
fileName: "installer.zip",
tag: '1.0.0',
id: '',
fileName: 'installer.zip',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -369,18 +371,18 @@ test("Fail when a release with no assets are obtained", async () => {
}
const result = downloader.download(downloadSettings)
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)
test("Download from latest prerelease", async () => {
test('Download from latest prerelease', async () => {
const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/slick-pg",
sourceRepoPath: 'robinraju/slick-pg',
isLatest: true,
preRelease: true,
tag: "",
id: "",
fileName: "pre-release.txt",
tag: '',
id: '',
fileName: 'pre-release.txt',
tarBall: false,
zipBall: false,
extractAssets: false,
@@ -390,31 +392,31 @@ test("Download from latest prerelease", async () => {
expect(result.length).toBe(1)
}, 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 = {
sourceRepoPath: "foo/slick-pg",
sourceRepoPath: 'foo/slick-pg',
isLatest: true,
preRelease: true,
tag: "",
id: "",
fileName: "installer.zip",
tag: '',
id: '',
fileName: 'installer.zip',
tarBall: false,
zipBall: false,
extractAssets: false,
outFilePath: outputFilePath
}
const result = downloader.download(downloadSettings)
await expect(result).rejects.toThrow("No prereleases found!")
await expect(result).rejects.toThrow('No prereleases found!')
}, 10000)
test("Download from a release containing only tarBall & zipBall", async () => {
test('Download from a release containing only tarBall & zipBall', async () => {
const downloadSettings: IReleaseDownloadSettings = {
sourceRepoPath: "robinraju/tar-zip-ball-only-repo",
sourceRepoPath: 'robinraju/tar-zip-ball-only-repo',
isLatest: true,
preRelease: false,
tag: "",
id: "",
fileName: "",
tag: '',
id: '',
fileName: '',
tarBall: true,
zipBall: true,
extractAssets: false,
+45 -32
View File
@@ -1,66 +1,79 @@
name: "release-downloader"
description: "Download release assets from private or public github repositories"
author: "Robin Raju"
name: 'release-downloader'
description:
'Download release assets from private or public github repositories'
author: 'Robin Raju'
inputs:
repository:
description: "The source repository path. Expected format {owner}/{repo}"
description: 'The source repository path. Expected format {owner}/{repo}'
default: ${{ github.repository }}
required: false
latest:
description: "A flag to choose between latest release and remaining releases"
default: "false"
description:
'A flag to choose between latest release and remaining releases'
default: 'false'
required: false
preRelease:
description: "A flag to download from prerelease. It should be combined with latest flag"
default: "false"
description:
'A flag to download from prerelease. It should be combined with latest
flag'
default: 'false'
required: false
tag:
description: "The github tag to download the release from"
default: ""
description: 'The github tag to download the release from'
default: ''
required: false
fileName:
description: "Name of the file to download (use '*' to download all assets other than tarball or zipball)"
default: ""
description:
"Name of the file to download (use '*' to download all assets other than
tarball or zipball)"
default: ''
required: false
tarBall:
description: "Download tarball from assets"
default: "false"
description: 'Download tarball from assets'
default: 'false'
required: false
zipBall:
description: "Download zipball from assets"
default: "false"
description: 'Download zipball from assets'
default: 'false'
required: false
out-file-path:
description: "Relative path under $GITHUB_WORKSPACE to place the downloaded files"
default: "."
description:
'Relative path under $GITHUB_WORKSPACE to place the downloaded files'
default: '.'
required: true
extract:
description: "If the downloaded assets should be extracted to `out-file-path`. Supports tar, tar.gz and zip"
default: "false"
description:
'If the downloaded assets should be extracted to `out-file-path`. Supports
tar, tar.gz and zip'
default: 'false'
required: false
token:
description: "Github token to access private repos"
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"
description:
'The URL of the Github API, only use this input if you are using Github
Enterprise'
default: 'https://api.github.com'
required: false
releaseId:
description: "The release id to download the file from"
default: ""
description: 'The release id to download the file from'
default: ''
required: false
outputs:
tag_name:
description: "The github tag used to download the release"
description: 'The github tag used to download the release'
release_name:
description: "The release name / title"
description: 'The release name / title'
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:
using: "node20"
main: "dist/index.js"
using: 'node20'
main: 'dist/index.js'
branding:
icon: "download"
color: "green"
icon: 'download'
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
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
MIT
(MIT)
@@ -145,22 +164,70 @@ SOFTWARE.
chownr
ISC
The ISC License
BlueOak-1.0.0
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
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.
# Blue Oak Model License
Version 1.0.0
## Purpose
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
@@ -238,25 +305,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
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
MIT
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.
"""
Copyright Isaac Z. Schlueter and Contributors
Copyright Node.js contributors. All rights reserved.
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
Copyright (c) 2017-2023 Isaac Z. Schlueter and Contributors
Copyright (c) 2017-2023 Node.js 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
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
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
MIT
@@ -831,19 +857,67 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
yallist
ISC
The ISC License
BlueOak-1.0.0
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
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.
# Blue Oak Model License
Version 1.0.0
## Purpose
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",
"version": "1.0.0",
"author": "Robin Raju",
"license": "MIT",
"private": true,
"description": "Github action to download release assets",
"main": "lib/main.js",
"exports": {
".": "./dist/index.js"
},
"engines": {
"node": ">=20"
},
"scripts": {
"build": "tsc",
"format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts",
"lint": "eslint src/**/*.ts",
"package": "ncc build --license licenses.txt",
"release": "npm run build && npm run package",
"test": "jest --detectOpenHandles",
"all": "npm run build && npm run format && npm run lint && npm run package && npm test"
"bundle": "npm run format:write && npm run package",
"ci-test": "npx jest",
"format:write": "npx prettier --write .",
"format:check": "npx prettier --check .",
"lint": "npx eslint . -c ./.github/linters/.eslintrc.yml",
"package": "npx ncc build src/main.ts -o dist --license licenses.txt",
"package:watch": "npm run package -- --watch",
"test": "npx jest",
"all": "npm run format:write && npm run lint && npm run test && npm run package"
},
"repository": {
"type": "git",
@@ -24,33 +32,60 @@
"setup",
"github release download"
],
"author": "Robin Raju",
"license": "MIT",
"jest": {
"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": {
"@actions/core": "^1.10.1",
"@actions/io": "^1.1.3",
"minimatch": "^9.0.4",
"node-stream-zip": "^1.15.0",
"tar": "^6.2.1",
"tar": "^7.0.1",
"typed-rest-client": "^1.8.11"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@types/jest": "^29.5.12",
"@types/node": "^20.12.7",
"@types/tar": "^6.1.12",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@typescript-eslint/eslint-plugin": "^7.7.1",
"@typescript-eslint/parser": "^7.7.1",
"@vercel/ncc": "^0.38.1",
"eslint": "^8.57.0",
"eslint-plugin-github": "^4.10.2",
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-jest": "^28.2.0",
"eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0",
"jest-circus": "^29.7.0",
"js-yaml": "^4.1.0",
"nock": "^13.5.4",
"prettier": "3.2.5",
"prettier-eslint": "^16.3.0",
"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 {
name: string
id: number
tag_name: String
tag_name: string
prerelease: boolean
assets: GhAsset[]
tarball_url: string
+16 -16
View File
@@ -1,9 +1,9 @@
import * as core from "@actions/core"
import * as path from "path"
import {IReleaseDownloadSettings} from "./download-settings"
import * as core from '@actions/core'
import * as path from 'path'
import { IReleaseDownloadSettings } from './download-settings'
function validateRepositoryPath(repositoryPath: string): void {
const repoParts = repositoryPath.split("/")
const repoParts = repositoryPath.split('/')
if (repoParts.length !== 2 || !repoParts[0] || !repoParts[1]) {
throw new Error(
`Invalid repository '${repositoryPath}'. Expected format {owner}/{repo}.`
@@ -24,19 +24,19 @@ function validateReleaseVersion(
}
export function getInputs(): IReleaseDownloadSettings {
let githubWorkspacePath = process.env["GITHUB_WORKSPACE"]
let githubWorkspacePath = process.env['GITHUB_WORKSPACE']
if (!githubWorkspacePath) {
throw new Error("$GITHUB_WORKSPACE not defined")
throw new Error('$GITHUB_WORKSPACE not defined')
}
githubWorkspacePath = path.resolve(githubWorkspacePath)
const repositoryPath = core.getInput("repository")
const repositoryPath = core.getInput('repository')
validateRepositoryPath(repositoryPath)
const latestFlag = core.getBooleanInput("latest")
const preReleaseFlag = core.getBooleanInput("preRelease")
const ghTag = core.getInput("tag")
const releaseId = core.getInput("releaseId")
const latestFlag = core.getBooleanInput('latest')
const preReleaseFlag = core.getBooleanInput('preRelease')
const ghTag = core.getInput('tag')
const releaseId = core.getInput('releaseId')
validateReleaseVersion(latestFlag, ghTag, releaseId)
@@ -46,13 +46,13 @@ export function getInputs(): IReleaseDownloadSettings {
preRelease: preReleaseFlag,
tag: ghTag,
id: releaseId,
fileName: core.getInput("fileName"),
tarBall: core.getBooleanInput("tarBall"),
zipBall: core.getBooleanInput("zipBall"),
extractAssets: core.getBooleanInput("extract"),
fileName: core.getInput('fileName'),
tarBall: core.getBooleanInput('tarBall'),
zipBall: core.getBooleanInput('zipBall'),
extractAssets: core.getBooleanInput('extract'),
outFilePath: path.resolve(
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 handlers from "typed-rest-client/Handlers"
import * as inputHelper from "./input-helper"
import * as thc from "typed-rest-client/HttpClient"
import * as core from '@actions/core'
import * as handlers from 'typed-rest-client/Handlers'
import * as inputHelper from './input-helper'
import * as thc from 'typed-rest-client/HttpClient'
import {ReleaseDownloader} from "./release-downloader"
import {extract} from "./unarchive"
import { ReleaseDownloader } from './release-downloader'
import { extract } from './unarchive'
async function run(): Promise<void> {
try {
const downloadSettings = inputHelper.getInputs()
const authToken = core.getInput("token")
const githubApiUrl = core.getInput("github-api-url")
const authToken = core.getInput('token')
const githubApiUrl = core.getInput('github-api-url')
const credentialHandler = new handlers.BearerCredentialHandler(
authToken,
false
)
const httpClient: thc.HttpClient = new thc.HttpClient("gh-api-client", [
const httpClient: thc.HttpClient = new thc.HttpClient('gh-api-client', [
credentialHandler
])
+30 -30
View File
@@ -1,14 +1,14 @@
import * as core from "@actions/core"
import * as fs from "fs"
import * as io from "@actions/io"
import * as path from "path"
import * as thc from "typed-rest-client/HttpClient"
import {minimatch} from "minimatch"
import * as core from '@actions/core'
import * as fs from 'fs'
import * as io from '@actions/io'
import * as path from 'path'
import * as thc from 'typed-rest-client/HttpClient'
import { minimatch } from 'minimatch'
import {DownloadMetaData, GithubRelease} from "./gh-api"
import {IHeaders, IHttpClientResponse} from "typed-rest-client/Interfaces"
import { DownloadMetaData, GithubRelease } from './gh-api'
import { IHeaders, IHttpClientResponse } from 'typed-rest-client/Interfaces'
import {IReleaseDownloadSettings} from "./download-settings"
import { IReleaseDownloadSettings } from './download-settings'
export class ReleaseDownloader {
private httpClient: thc.HttpClient
@@ -30,19 +30,19 @@ export class ReleaseDownloader {
downloadSettings.sourceRepoPath,
downloadSettings.preRelease
)
} else if (downloadSettings.tag !== "") {
} else if (downloadSettings.tag !== '') {
ghRelease = await this.getReleaseByTag(
downloadSettings.sourceRepoPath,
downloadSettings.tag
)
} else if (downloadSettings.id !== "") {
} else if (downloadSettings.id !== '') {
ghRelease = await this.getReleaseById(
downloadSettings.sourceRepoPath,
downloadSettings.id
)
} else {
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
core.setOutput("tag_name", ghRelease.tag_name)
core.setOutput("release_name", ghRelease.name)
core.setOutput("downloaded_files", result)
core.setOutput('tag_name', ghRelease.tag_name)
core.setOutput('release_name', ghRelease.name)
core.setOutput('downloaded_files', result)
return result
}
@@ -74,7 +74,7 @@ export class ReleaseDownloader {
): Promise<GithubRelease> {
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
if (!preRelease) {
@@ -112,7 +112,7 @@ export class ReleaseDownloader {
release = latestPreRelease
core.info(`Found latest pre-release version: ${release.tag_name}`)
} else {
throw new Error("No prereleases found!")
throw new Error('No prereleases found!')
}
}
@@ -130,11 +130,11 @@ export class ReleaseDownloader {
): Promise<GithubRelease> {
core.info(`Fetching release ${tag} from repo ${repoPath}`)
if (tag === "") {
throw new Error("Config error: Please input a valid tag")
if (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(
`${this.apiRoot}/repos/${repoPath}/releases/tags/${tag}`,
@@ -166,11 +166,11 @@ export class ReleaseDownloader {
): Promise<GithubRelease> {
core.info(`Fetching release id:${id} from repo ${repoPath}`)
if (id === "") {
throw new Error("Config error: Please input a valid release ID")
if (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(
`${this.apiRoot}/repos/${repoPath}/releases/${id}`,
@@ -207,7 +207,7 @@ export class ReleaseDownloader {
const dData: DownloadMetaData = {
fileName: asset.name,
url: asset["url"],
url: asset['url'],
isTarBallOrZipBall: false
}
downloads.push(dData)
@@ -224,7 +224,7 @@ export class ReleaseDownloader {
}
if (downloadSettings.tarBall) {
const repoName = downloadSettings.sourceRepoPath.split("/")[1]
const repoName = downloadSettings.sourceRepoPath.split('/')[1]
downloads.push({
fileName: `${repoName}-${ghRelease.tag_name}.tar.gz`,
url: ghRelease.tarball_url,
@@ -233,7 +233,7 @@ export class ReleaseDownloader {
}
if (downloadSettings.zipBall) {
const repoName = downloadSettings.sourceRepoPath.split("/")[1]
const repoName = downloadSettings.sourceRepoPath.split('/')[1]
downloads.push({
fileName: `${repoName}-${ghRelease.tag_name}.zip`,
url: ghRelease.zipball_url,
@@ -274,11 +274,11 @@ export class ReleaseDownloader {
outputPath: string
): Promise<string> {
const headers: IHeaders = {
Accept: "application/octet-stream"
Accept: 'application/octet-stream'
}
if (asset.isTarBallOrZipBall) {
headers["Accept"] = "*/*"
headers['Accept'] = '*/*'
}
core.info(`Downloading file: ${asset.fileName} to: ${outputPath}`)
@@ -303,10 +303,10 @@ export class ReleaseDownloader {
const fileStream: fs.WriteStream = fs.createWriteStream(outFilePath)
return new Promise((resolve, reject) => {
fileStream.on("error", err => reject(err))
fileStream.on('error', err => reject(err))
const outStream = httpClientResponse.message.pipe(fileStream)
outStream.on("close", () => {
outStream.on('close', () => {
resolve(outFilePath)
})
})
+9 -9
View File
@@ -1,15 +1,15 @@
import * as core from "@actions/core"
import * as fs from "fs"
import * as path from "path"
import * as tar from "tar"
import * as StreamZip from "node-stream-zip"
import * as core from '@actions/core'
import * as fs from 'fs'
import * as path from 'path'
import * as tar from 'tar'
import * as StreamZip from 'node-stream-zip'
export const extract = async (
filePath: string,
destDir: string
): Promise<void> => {
const isTarGz = filePath.endsWith(".tar.gz") || filePath.endsWith(".tar")
const isZip = filePath.endsWith(".zip")
const isTarGz = filePath.endsWith('.tar.gz') || filePath.endsWith('.tar')
const isZip = filePath.endsWith('.zip')
const filename = path.basename(filePath)
if (!isTarGz && !isZip) {
@@ -21,7 +21,7 @@ export const extract = async (
// Create the destination directory if it doesn't already exist
if (!fs.existsSync(destDir)) {
fs.mkdirSync(destDir, {recursive: true})
fs.mkdirSync(destDir, { recursive: true })
}
// Extract the file to the destination directory
@@ -32,7 +32,7 @@ export const extract = async (
})
}
if (isZip) {
const zip = new StreamZip.async({file: filePath})
const zip = new StreamZip.async({ file: filePath })
await zip.extract(null, destDir)
await zip.close()
}
+16 -9
View File
@@ -1,12 +1,19 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"outDir": "./lib", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"target": "ES2022",
"module": "NodeNext",
"rootDir": "./src",
"moduleResolution": "NodeNext",
"baseUrl": "./",
"sourceMap": true,
"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"]
}