Compare commits
117 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d39a63126 | ||
|
|
8c3a64de32 | ||
|
|
564c9d0297 | ||
|
|
48cd5a6793 | ||
|
|
029d95066b | ||
|
|
b9ed39f728 | ||
|
|
ba4d22f251 | ||
|
|
22f216e584 | ||
|
|
9a08425079 | ||
|
|
ac5977570e | ||
|
|
fe2a95a0cb | ||
|
|
46653ba3cb | ||
|
|
79269eb4bf | ||
|
|
4833470995 | ||
|
|
2de4236b17 | ||
|
|
23073eb4a2 | ||
|
|
faf614822d | ||
|
|
bde81b096d | ||
|
|
f1783122af | ||
|
|
404c7849e4 | ||
|
|
0b99e5f60d | ||
|
|
40030c0eb0 | ||
|
|
5e7113f543 | ||
|
|
90c8dc6d0b | ||
|
|
98c1e7eab7 | ||
|
|
eaa1f7c20f | ||
|
|
ce1d329288 | ||
|
|
9dbafb83da | ||
|
|
64305dab94 | ||
|
|
e95cd87648 | ||
|
|
7f4037254e | ||
|
|
e521d9e753 | ||
|
|
cc7196aa1d | ||
|
|
6ce7577c5e | ||
|
|
92bd8a3cd0 | ||
|
|
280935cb1a | ||
|
|
272ad859dc | ||
|
|
c5e64443ea | ||
|
|
9b1e76ea45 | ||
|
|
37b7aca7eb | ||
|
|
f87b4a0b81 | ||
|
|
6961202f36 | ||
|
|
4eab40be13 | ||
|
|
8701e46f41 | ||
|
|
565ec2459a | ||
|
|
ec4518c513 | ||
|
|
33300d7916 | ||
|
|
e048663cdf | ||
|
|
0e86ee6891 | ||
|
|
a31a43afa6 | ||
|
|
56849b848a | ||
|
|
000223ef3e | ||
|
|
df897cea27 | ||
|
|
b77daeff53 | ||
|
|
7515f7a4f9 | ||
|
|
3e14cd73d4 | ||
|
|
5e4787da1c | ||
|
|
355299fa7d | ||
|
|
5263253279 | ||
|
|
d6bf5f6a97 | ||
|
|
4afcc8f713 | ||
|
|
1472d90599 | ||
|
|
09f7b84634 | ||
|
|
5aa567b6f7 | ||
|
|
1979f24cbb | ||
|
|
6a5e08c48d | ||
|
|
f804442fe4 | ||
|
|
5282013b71 | ||
|
|
4d762a4bc3 | ||
|
|
aac34a9f33 | ||
|
|
406ce0281d | ||
|
|
72cc4b27b0 | ||
|
|
7d188d1776 | ||
|
|
81676df338 | ||
|
|
cfbae0ac37 | ||
|
|
f556b07dce | ||
|
|
8283350471 | ||
|
|
1a7a0291b8 | ||
|
|
38d4003d57 | ||
|
|
bf6c02443a | ||
|
|
e9faf3233c | ||
|
|
9ff1e31776 | ||
|
|
0739cce1e8 | ||
|
|
ef5d9ac398 | ||
|
|
1369f0ca05 | ||
|
|
372546727d | ||
|
|
324039ba0a | ||
|
|
508f6970a5 | ||
|
|
e6a9d9c802 | ||
|
|
21a6c99c5d | ||
|
|
db4d66086a | ||
|
|
c8087bcc70 | ||
|
|
75db2288ca | ||
|
|
cbfc7d9ca3 | ||
|
|
d846be5128 | ||
|
|
15db109d58 | ||
|
|
94d1202726 | ||
|
|
8e78cd925d | ||
|
|
c6b1d83a14 | ||
|
|
b7877514c6 | ||
|
|
370a350353 | ||
|
|
ba58e0e966 | ||
|
|
106b04e076 | ||
|
|
04947a51f3 | ||
|
|
7d96e1e541 | ||
|
|
5003595d8e | ||
|
|
263c5d855a | ||
|
|
36894fd813 | ||
|
|
a22ff2a7c5 | ||
|
|
8c24449b56 | ||
|
|
0994e6c0d2 | ||
|
|
334f20f7fa | ||
|
|
93d3863084 | ||
|
|
e7ecd94635 | ||
|
|
c253b9d27a | ||
|
|
248e3651e3 | ||
|
|
fd4e8f971f |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"plugins": ["jest", "@typescript-eslint"],
|
"plugins": ["jest", "@typescript-eslint"],
|
||||||
"extends": ["plugin:github/es6"],
|
"extends": ["plugin:github/recommended","plugin:@typescript-eslint/recommended"],
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 9,
|
"ecmaVersion": 9,
|
||||||
@@ -17,13 +17,29 @@
|
|||||||
"@typescript-eslint/no-require-imports": "error",
|
"@typescript-eslint/no-require-imports": "error",
|
||||||
"@typescript-eslint/array-type": "error",
|
"@typescript-eslint/array-type": "error",
|
||||||
"@typescript-eslint/await-thenable": "error",
|
"@typescript-eslint/await-thenable": "error",
|
||||||
"@typescript-eslint/ban-ts-ignore": "error",
|
"@typescript-eslint/ban-ts-comment": "error",
|
||||||
"camelcase": "off",
|
"camelcase": "off",
|
||||||
"@typescript-eslint/camelcase": "error",
|
"@typescript-eslint/naming-convention": [
|
||||||
"@typescript-eslint/class-name-casing": "error",
|
"error",
|
||||||
|
{
|
||||||
|
"selector": "class",
|
||||||
|
"format": ["PascalCase"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selector": "interface",
|
||||||
|
"format": ["PascalCase"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selector": "typeProperty",
|
||||||
|
"format": [],
|
||||||
|
"custom": {
|
||||||
|
"regex": "^[A-Z][A-Za-z]*$",
|
||||||
|
"match": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
|
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
|
||||||
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
||||||
"@typescript-eslint/generic-type-naming": ["error", "^[A-Z][A-Za-z]*$"],
|
|
||||||
"@typescript-eslint/no-array-constructor": "error",
|
"@typescript-eslint/no-array-constructor": "error",
|
||||||
"@typescript-eslint/no-empty-interface": "error",
|
"@typescript-eslint/no-empty-interface": "error",
|
||||||
"@typescript-eslint/no-explicit-any": "error",
|
"@typescript-eslint/no-explicit-any": "error",
|
||||||
@@ -33,7 +49,7 @@
|
|||||||
"@typescript-eslint/no-misused-new": "error",
|
"@typescript-eslint/no-misused-new": "error",
|
||||||
"@typescript-eslint/no-namespace": "error",
|
"@typescript-eslint/no-namespace": "error",
|
||||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||||
"@typescript-eslint/no-object-literal-type-assertion": "error",
|
"@typescript-eslint/consistent-type-assertions": "error",
|
||||||
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
||||||
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
||||||
"@typescript-eslint/no-useless-constructor": "error",
|
"@typescript-eslint/no-useless-constructor": "error",
|
||||||
@@ -41,7 +57,7 @@
|
|||||||
"@typescript-eslint/prefer-for-of": "warn",
|
"@typescript-eslint/prefer-for-of": "warn",
|
||||||
"@typescript-eslint/prefer-function-type": "warn",
|
"@typescript-eslint/prefer-function-type": "warn",
|
||||||
"@typescript-eslint/prefer-includes": "error",
|
"@typescript-eslint/prefer-includes": "error",
|
||||||
"@typescript-eslint/prefer-interface": "error",
|
"@typescript-eslint/consistent-type-definitions": "error",
|
||||||
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
||||||
"@typescript-eslint/promise-function-async": "error",
|
"@typescript-eslint/promise-function-async": "error",
|
||||||
"@typescript-eslint/require-array-sort-compare": "error",
|
"@typescript-eslint/require-array-sort-compare": "error",
|
||||||
@@ -50,7 +66,10 @@
|
|||||||
"@typescript-eslint/semi": ["error", "never"],
|
"@typescript-eslint/semi": ["error", "never"],
|
||||||
"@typescript-eslint/type-annotation-spacing": "error",
|
"@typescript-eslint/type-annotation-spacing": "error",
|
||||||
"@typescript-eslint/unbound-method": "error",
|
"@typescript-eslint/unbound-method": "error",
|
||||||
"no-console": "off"
|
"no-console": "off",
|
||||||
|
"import/no-unresolved": "off",
|
||||||
|
"sort-imports": "off",
|
||||||
|
"filenames/match-regex": "off"
|
||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"node": true,
|
"node": true,
|
||||||
|
|||||||
4
.github/workflows/check-dist.yml
vendored
4
.github/workflows/check-dist.yml
vendored
@@ -24,10 +24,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Set Node.js 12.x
|
- name: Set Node.js 16.x
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 12.x
|
node-version: 16.x
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|||||||
13
.github/workflows/test.yml
vendored
13
.github/workflows/test.yml
vendored
@@ -7,6 +7,9 @@ on: # rebuild any PRs and main branch changes
|
|||||||
- main
|
- main
|
||||||
- 'releases/*'
|
- 'releases/*'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
package: # make sure build/ci work properly
|
package: # make sure build/ci work properly
|
||||||
@@ -15,6 +18,9 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
name: Checkout Delete Package Versions Repo
|
name: Checkout Delete Package Versions Repo
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
- run: npm install
|
- run: npm install
|
||||||
name: NPM Install
|
name: NPM Install
|
||||||
- run: npm run pack
|
- run: npm run pack
|
||||||
@@ -26,9 +32,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
name: Checkout Delete Package Versions Repo
|
name: Checkout Delete Package Versions Repo
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
- uses: ./
|
- uses: ./
|
||||||
name: Smoke Test Delete Package Versions Action
|
name: Smoke Test Delete Package Versions Action
|
||||||
with:
|
with:
|
||||||
package-name: 'com.github.actions.test-package'
|
package-name: 'action-ci-test-package'
|
||||||
|
package-type: 'npm'
|
||||||
num-old-versions-to-delete: 0
|
num-old-versions-to-delete: 0
|
||||||
min-versions-to-keep: 0
|
|
||||||
2
.licenses/npm/@actions/core.dep.yml
generated
2
.licenses/npm/@actions/core.dep.yml
generated
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: "@actions/core"
|
name: "@actions/core"
|
||||||
version: 1.6.0
|
version: 1.9.1
|
||||||
type: npm
|
type: npm
|
||||||
summary: Actions core lib
|
summary: Actions core lib
|
||||||
homepage: https://github.com/actions/toolkit/tree/master/packages/core
|
homepage: https://github.com/actions/toolkit/tree/master/packages/core
|
||||||
|
|||||||
2
.licenses/npm/@octokit/rest.dep.yml
generated
2
.licenses/npm/@octokit/rest.dep.yml
generated
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: "@octokit/rest"
|
name: "@octokit/rest"
|
||||||
version: 16.43.1
|
version: 19.0.5
|
||||||
type: npm
|
type: npm
|
||||||
summary: GitHub REST API client for Node.js
|
summary: GitHub REST API client for Node.js
|
||||||
homepage: https://github.com/octokit/rest.js#readme
|
homepage: https://github.com/octokit/rest.js#readme
|
||||||
|
|||||||
2
.licenses/npm/rxjs.dep.yml
generated
2
.licenses/npm/rxjs.dep.yml
generated
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: rxjs
|
name: rxjs
|
||||||
version: 6.5.4
|
version: 6.6.7
|
||||||
type: npm
|
type: npm
|
||||||
summary: Reactive Extensions for modern JavaScript
|
summary: Reactive Extensions for modern JavaScript
|
||||||
homepage: https://github.com/ReactiveX/RxJS
|
homepage: https://github.com/ReactiveX/RxJS
|
||||||
|
|||||||
253
README.md
253
README.md
@@ -1,117 +1,142 @@
|
|||||||
# Delete Package Versions
|
# Delete Package Versions
|
||||||
|
|
||||||
This action deletes versions of a package from [GitHub Packages](https://github.com/features/packages).
|
This action deletes versions of a package from [GitHub Packages](https://github.com/features/packages). This action will only delete a maximum of 100 versions in one run.
|
||||||
|
|
||||||
### What It Can Do
|
### What It Can Do
|
||||||
|
|
||||||
* Create a retention policy (delete all except n most recent pre-release versions)
|
* Create a retention policy (delete all except n most recent pre-release versions)
|
||||||
* Delete all package versions except n most recent versions.
|
* Delete all package versions except n most recent versions
|
||||||
* Delete oldest version(s)
|
* Delete oldest version(s)
|
||||||
* Ignore version(s) from deletion through regex.
|
* Ignore version(s) from deletion through regex
|
||||||
* Delete version(s) of a package that is hosted in the same repo that is executing the workflow
|
* Delete version(s) of a package that is hosted from a repo having access to package
|
||||||
* Delete version(s) of a package that is hosted in a different repo than the one executing the workflow
|
* Delete version(s) of a package that is hosted from a repo not having access to package
|
||||||
* Delete a single version
|
* Delete a single version
|
||||||
* Delete multiple versions
|
* Delete multiple versions
|
||||||
|
|
||||||
|
|
||||||
* Delete specific version(s)
|
* Delete specific version(s)
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
# Can be a single package version id, or a comma separated list of package version ids.
|
# Can be a single package version id, or a comma separated list of package version ids.
|
||||||
# Defaults to an empty string.
|
# Defaults to an empty string.
|
||||||
package-version-ids:
|
package-version-ids:
|
||||||
|
|
||||||
# Owner of the repo hosting the package.
|
# Owner of the package.
|
||||||
# Defaults to the owner of the repo executing the workflow.
|
# Defaults to the owner of the repo executing the workflow.
|
||||||
# Required if deleting a version from a package hosted in a different repo than the one executing the workflow.
|
# Required if deleting a version from a package hosted in a different org than the one executing the workflow.
|
||||||
owner:
|
owner:
|
||||||
|
|
||||||
# Repo hosting the package.
|
|
||||||
# Defaults to the repo executing the workflow.
|
|
||||||
# Required if deleting a version from a package hosted in a different repo than the one executing the workflow.
|
|
||||||
repo:
|
|
||||||
|
|
||||||
# Name of the package.
|
# Name of the package.
|
||||||
# Defaults to an empty string.
|
# Required
|
||||||
# Required if `package-version-ids` input is not given.
|
|
||||||
package-name:
|
package-name:
|
||||||
|
|
||||||
|
# Type of the package. Can be one of container, maven, npm, nuget, or rubygems.
|
||||||
|
# Required
|
||||||
|
package-type:
|
||||||
|
|
||||||
# The number of old versions to delete starting from the oldest version.
|
# The number of old versions to delete starting from the oldest version.
|
||||||
# Defaults to 1.
|
# Defaults to 1.
|
||||||
# Cannot be more than 100.
|
|
||||||
num-old-versions-to-delete:
|
num-old-versions-to-delete:
|
||||||
|
|
||||||
# The number of latest versions to not delete.
|
# The number of latest versions to keep.
|
||||||
# Defaults to 0.
|
# This cannot be specified with `num-old-versions-to-delete`. By default, `min-versions-to-keep` takes precedence over `num-old-versions-to-delete`.
|
||||||
# When this is set greater than 0 it will delete all deletable package versions except the specified no.
|
# When set to 0, all deletable versions will be deleted.
|
||||||
# `num-old-versions-to-delete` will not be taken into account with this option.
|
# When set greater than 0, all deletable package versions except the specified number will be deleted.
|
||||||
# Cannot be more than 100.
|
|
||||||
min-versions-to-keep:
|
min-versions-to-keep:
|
||||||
|
|
||||||
# The package versions to exclude from deletion.
|
# The package versions to exclude from deletion.
|
||||||
# Takes regex for the version name as input.
|
# Takes regex for the version name as input.
|
||||||
# By default nothing is ignored.
|
# By default nothing is ignored. This is ignored when `delete-only-pre-release-versions` is true
|
||||||
ignore-versions:
|
ignore-versions:
|
||||||
|
|
||||||
# If true it will delete only the pre-release versions.
|
# If true it will delete only the pre-release versions.
|
||||||
# The number of pre-release versions to keep can be set by using `min-versions-to-keep` value with this.
|
# The number of pre-release versions to keep can be set by using `min-versions-to-keep` value with this.
|
||||||
# When `min-versions-to-keep` is 0, all pre-release versions get deleted.
|
# When `min-versions-to-keep` is 0, all pre-release versions get deleted.
|
||||||
# Defaults to false.
|
# Defaults to false.
|
||||||
|
# Cannot be used with `num-old-versions-to-delete` and `ignore-versions`.
|
||||||
delete-only-pre-release-versions:
|
delete-only-pre-release-versions:
|
||||||
|
|
||||||
|
# If true it will delete only the untagged versions in case of container package.
|
||||||
|
# Does not work for other package types and will be ignored.
|
||||||
|
# The number of untagged versions to keep can be set by using `min-versions-to-keep` value with this.
|
||||||
|
# When `min-versions-to-keep` is 0, all untagged versions get deleted.
|
||||||
|
# Defaults to false.
|
||||||
|
# Cannot be used with `num-old-versions-to-delete`.
|
||||||
|
delete-only-untagged-versions:
|
||||||
|
|
||||||
# The token used to authenticate with GitHub Packages.
|
# The token used to authenticate with GitHub Packages.
|
||||||
# Defaults to github.token.
|
# Defaults to github.token.
|
||||||
# Required if deleting a version from a package hosted in a different repo than the one executing the workflow.
|
# Required if the repo running the workflow does not have access to delete the package.
|
||||||
|
# For rubygems and maven package, repo has access if package is hosted in the same repo as the workflow.
|
||||||
|
# For container, npm and nuget package, repo has access if assigned **Admin** role under Package Settings > Manage Actions Access.
|
||||||
# If `package-version-ids` is given the token only needs the delete packages scope.
|
# If `package-version-ids` is given the token only needs the delete packages scope.
|
||||||
# If `package-version-ids` is not given the token needs the delete packages scope and the read packages scope
|
# If `package-version-ids` is not given the token needs the delete packages scope and the read packages scope
|
||||||
token:
|
token:
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Valid Input Combinations
|
||||||
|
|
||||||
|
`owner`, `package-name`, `package-type` and `token` can be used with the following combinations in a workflow -
|
||||||
|
|
||||||
|
- `num-old-versions-to-delete`
|
||||||
|
- `min-versions-to-keep`
|
||||||
|
- `delete-only-pre-release-versions`
|
||||||
|
- `ignore-versions`
|
||||||
|
- `num-old-versions-to-delete` + `ignore-versions`
|
||||||
|
- `min-versions-to-keep` + `ignore-versions`
|
||||||
|
- `min-versions-to-keep` + `delete-only-pre-release-versions`
|
||||||
|
- `delete-only-untagged-versions`
|
||||||
|
- `min-versions-to-keep` + `delete-only-untagged-versions`
|
||||||
|
|
||||||
# Scenarios
|
# Scenarios
|
||||||
|
|
||||||
- [Delete all pre-release versions except y latest pre-release package versions](#delete-all-pre-release-versions-except-y-latest-pre-release-package-versions)
|
- [Delete Package Versions](#delete-package-versions)
|
||||||
- [Delete all except y latest versions while ignoring particular package versions](#delete-all-except-y-latest-versions-while-ignoring-particular-package-versions)
|
- [What It Can Do](#what-it-can-do)
|
||||||
- [Delete oldest x number of versions while ignoring particular package versions](#delete-oldest-x-number-of-versions-while-ignoring-particular-package-versions)
|
- [Usage](#usage)
|
||||||
- [Delete all except y latest versions of a package](#delete-all-except-y-latest-versions-of-a-package)
|
- [Valid Input Combinations](#valid-input-combinations)
|
||||||
- [Delete oldest x number of versions of a package](#delete-oldest-x-number-of-versions-of-a-package)
|
- [Scenarios](#scenarios)
|
||||||
- [Delete oldest version of a package](#delete-oldest-version-of-a-package)
|
- [Delete all pre-release versions except y latest pre-release package versions](#delete-all-pre-release-versions-except-y-latest-pre-release-package-versions)
|
||||||
- [Delete a specific version of a package](#delete-a-specific-version-of-a-package)
|
- [Delete all untagged container versions except y latest untagged versions](#delete-all-untagged-container-versions-except-y-latest-untagged-versions)
|
||||||
- [Delete multiple specific versions of a package](#delete-multiple-specific-versions-of-a-package)
|
- [Delete all except y latest versions while ignoring particular package versions](#delete-all-except-y-latest-versions-while-ignoring-particular-package-versions)
|
||||||
|
- [Delete oldest x number of versions while ignoring particular package versions](#delete-oldest-x-number-of-versions-while-ignoring-particular-package-versions)
|
||||||
|
- [Delete all except y latest versions of a package](#delete-all-except-y-latest-versions-of-a-package)
|
||||||
|
- [Delete oldest x number of versions of a package](#delete-oldest-x-number-of-versions-of-a-package)
|
||||||
|
- [Delete oldest version of a package](#delete-oldest-version-of-a-package)
|
||||||
|
- [Delete a specific version of a package](#delete-a-specific-version-of-a-package)
|
||||||
|
- [Delete multiple specific versions of a package](#delete-multiple-specific-versions-of-a-package)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
|
|
||||||
### Delete all pre-release versions except y latest pre-release package versions
|
### Delete all pre-release versions except y latest pre-release package versions
|
||||||
|
|
||||||
To delete all pre release versions except y latest pre-release package versions in the same repo as the workflow the __package-name__, __min-versions-to-keep__ and __delete-only-pre-release-versions__ inputs are required.
|
To delete all pre release versions except y latest pre-release package versions, the __package-name__, __min-versions-to-keep__ and __delete-only-pre-release-versions__ inputs are required.
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
Delete all pre-release package versions except latest 10 in the same repo as the workflow
|
Delete all pre-release package versions except latest 10
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
package-name: 'test-package'
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
min-versions-to-keep: 10
|
min-versions-to-keep: 10
|
||||||
delete-only-pre-release-versions: "true"
|
delete-only-pre-release-versions: "true"
|
||||||
```
|
```
|
||||||
To delete all pre release versions except y latest pre-release package versions in a different repo than the workflow the __owner__, __repo__, __package-name__, __token__, __min-versions-to-keep__ and __delete-only-pre-release-versions__ inputs are required.
|
To delete all pre release versions except y latest pre-release package versions from a repo not having access to package, the __owner__, __package-name__, __token__, __min-versions-to-keep__ and __delete-only-pre-release-versions__ inputs are required.
|
||||||
|
|
||||||
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
Delete all pre-release package versions except latest 10 in a different repo than the workflow
|
Delete all pre-release package versions except latest 10 from a repo not having access to package
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
owner: 'github'
|
owner: 'github'
|
||||||
repo: 'packages'
|
|
||||||
package-name: 'test-package'
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
token: ${{ secrets.GITHUB_PAT }}
|
token: ${{ secrets.GITHUB_PAT }}
|
||||||
min-versions-to-keep: 10
|
min-versions-to-keep: 10
|
||||||
delete-only-pre-release-versions: "true"
|
delete-only-pre-release-versions: "true"
|
||||||
@@ -119,36 +144,56 @@ This action deletes versions of a package from [GitHub Packages](https://github.
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
### Delete all except y latest versions while ignoring particular package versions
|
### Delete all untagged container versions except y latest untagged versions
|
||||||
|
|
||||||
To delete all except y latest versions while ignoring particular package versions in the same repo as the workflow the __package-name__, __min-versions-to-keep__ and __ignore-versions__ inputs are required.
|
To delete all untagged versions of a container package except y latest untagged versions, the __package-name__, __package-type__, __min-versions-to-keep__ and __delete-only-untagged-versions__ inputs are required. __package-type__ must be container for this scenario.
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
Delete all except latest 3 package versions excluding major versions as per semver in the same repo as the workflow
|
Delete all untagged versions except latest 10
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
package-name: 'test-packae'
|
package-name: 'test-package'
|
||||||
|
package-type: 'container'
|
||||||
|
min-versions-to-keep: 10
|
||||||
|
delete-only-untagged-versions: 'true'
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### Delete all except y latest versions while ignoring particular package versions
|
||||||
|
|
||||||
|
To delete all except y latest versions while ignoring particular package versions, the __package-name__, __min-versions-to-keep__ and __ignore-versions__ inputs are required.
|
||||||
|
|
||||||
|
__Example__
|
||||||
|
|
||||||
|
Delete all except latest 3 package versions excluding major versions as per semver
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- uses: actions/delete-package-versions@v4
|
||||||
|
with:
|
||||||
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
min-versions-to-keep: 3
|
min-versions-to-keep: 3
|
||||||
ignore-versions: '^(0|[1-9]\\d*)\\.0\\.0$'
|
ignore-versions: '^(0|[1-9]\\d*)\\.0\\.0$'
|
||||||
```
|
```
|
||||||
|
|
||||||
To delete all except y latest versions while ignoring particular package versions in a different repo than the workflow the __owner__, __repo__, __package-name__, __token__, __min-versions-to-keep__ and __ignore-versions__ inputs are required.
|
To delete all except y latest versions while ignoring particular package versions from a repo not having access to package, the __owner__, __package-name__, __token__, __min-versions-to-keep__ and __ignore-versions__ inputs are required.
|
||||||
|
|
||||||
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
Delete all except latest 3 package versions excluding major versions as per semver in a different repo than the workflow
|
Delete all except latest 3 package versions excluding major versions as per semver from a repo not having access to package
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
owner: 'github'
|
owner: 'github'
|
||||||
repo: 'packages'
|
package-name: 'test-package'
|
||||||
package-name: 'test-packae'
|
package-type: 'npm'
|
||||||
token: ${{ secrets.GITHUB_PAT }}
|
token: ${{ secrets.GITHUB_PAT }}
|
||||||
min-versions-to-keep: 3
|
min-versions-to-keep: 3
|
||||||
ignore-versions: '^(0|[1-9]\\d*)\\.0\\.0$'
|
ignore-versions: '^(0|[1-9]\\d*)\\.0\\.0$'
|
||||||
@@ -158,38 +203,37 @@ This action deletes versions of a package from [GitHub Packages](https://github.
|
|||||||
|
|
||||||
### Delete oldest x number of versions while ignoring particular package versions
|
### Delete oldest x number of versions while ignoring particular package versions
|
||||||
|
|
||||||
To delete oldest x number of versions while ignoring all the major package versions in the same repo as the workflow the __package-name__, __num-oldest-versions-to-delete__ and __ignore-versions__ inputs are required.
|
To delete oldest x number of versions while ignoring all the major package versions, the __package-name__, __num-oldest-versions-to-delete__ and __ignore-versions__ inputs are required.
|
||||||
|
|
||||||
There is a possibility if the oldest x number of versions contain ignored package versions, actual package versions to get deleted will be less than x.
|
There is a possibility if the oldest x number of versions contain ignored package versions, actual package versions to get deleted will be less than x.
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
Delete 3 oldest versions excluding major versions as per semver is the same repo as the workflow
|
Delete 3 oldest versions excluding major versions as per semver
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
package-name: 'test-packae'
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
num-old-versions-to-delete: 3
|
num-old-versions-to-delete: 3
|
||||||
ignore-versions: '^(0|[1-9]\\d*)\\.0\\.0$'
|
ignore-versions: '^(0|[1-9]\\d*)\\.0\\.0$'
|
||||||
```
|
```
|
||||||
|
|
||||||
To delete oldest x number of versions while ignoring all the major package versions in a different repo than the workflow the __owner__, __repo__, __package-name__, __token__, __num-oldest-versions-to-delete__ and __ignore-versions__ inputs are required.
|
To delete oldest x number of versions while ignoring all the major package versions from a repo not having access to package, the __owner__, __package-name__, __token__, __num-oldest-versions-to-delete__ and __ignore-versions__ inputs are required.
|
||||||
|
|
||||||
There is a possibility if the oldest x number of versions contain ignored package versions, actual package versions to get deleted will be less than x.
|
There is a possibility if the oldest x number of versions contain ignored package versions, actual package versions to get deleted will be less than x.
|
||||||
|
|
||||||
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
Delete 3 oldest versions excluding major versions as per semver is a differernt repo than the workflow
|
Delete 3 oldest versions excluding major versions as per semver from a repo not having access to package
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
owner: 'github'
|
owner: 'github'
|
||||||
repo: 'packages'
|
package-name: 'test-package'
|
||||||
package-name: 'test-packae'
|
package-type: 'npm'
|
||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.PAT }}
|
||||||
num-old-versions-to-delete: 3
|
num-old-versions-to-delete: 3
|
||||||
ignore-versions: '^(0|[1-9]\\d*)\\.0\\.0$'
|
ignore-versions: '^(0|[1-9]\\d*)\\.0\\.0$'
|
||||||
@@ -199,33 +243,34 @@ This action deletes versions of a package from [GitHub Packages](https://github.
|
|||||||
|
|
||||||
### Delete all except y latest versions of a package
|
### Delete all except y latest versions of a package
|
||||||
|
|
||||||
To delete all except y latest versions of a package hosted in the same repo as the workflow the __package-name__ and __min-versions-to-keep__ inputs are required.
|
To delete all except y latest versions of a package hosted, the __package-name__ and __min-versions-to-keep__ inputs are required.
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
Delete all except latest 2 versions of a package hosted in the same repo as the workflow
|
Delete all except latest 2 versions of a package hosted
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
package-name: 'test-package'
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
min-versions-to-keep: 2
|
min-versions-to-keep: 2
|
||||||
```
|
```
|
||||||
|
|
||||||
To delete all except y latest versions of a package hosted in a repo other than the workflow the __owner__, __repo__, __package-name__, __token__ and __min-versions-to-keep__ inputs are required.
|
To delete all except y latest versions of a package hosted from a repo not having access to package, the __owner__, __package-name__, __token__ and __min-versions-to-keep__ inputs are required.
|
||||||
|
|
||||||
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
Delete all except latest 2 versions of a package hosted in a repo other than the workflow
|
Delete all except latest 2 versions of a package hosted from a repo not having access to package
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
owner: 'github'
|
owner: 'github'
|
||||||
repo: 'packages'
|
|
||||||
package-name: 'test-package'
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.PAT }}
|
||||||
min-versions-to-keep: 2
|
min-versions-to-keep: 2
|
||||||
```
|
```
|
||||||
@@ -234,33 +279,34 @@ This action deletes versions of a package from [GitHub Packages](https://github.
|
|||||||
|
|
||||||
### Delete oldest x number of versions of a package
|
### Delete oldest x number of versions of a package
|
||||||
|
|
||||||
To delete the oldest x number of versions of a package hosted in the same repo as the workflow the __package-name__, and __num-old-versions-to-delete__ inputs are required.
|
To delete the oldest x number of versions of a package hosted, the __package-name__, and __num-old-versions-to-delete__ inputs are required.
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
Delete the oldest 3 version of a package hosted in the same repo as the workflow
|
Delete the oldest 3 version of a package hosted
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
package-name: 'test-package'
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
num-old-versions-to-delete: 3
|
num-old-versions-to-delete: 3
|
||||||
```
|
```
|
||||||
|
|
||||||
To delete the oldest x number of versions of a package hosted in a different repo than the workflow the __owner__, __repo__, __package-name__, __token__ and __num-old-versions-to-delete__ inputs are required.
|
To delete the oldest x number of versions of a package hosted from a repo not having access to package, the __owner__, __package-name__, __token__ and __num-old-versions-to-delete__ inputs are required.
|
||||||
|
|
||||||
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
Delete the oldest 3 version of a package hosted in a different repo than the one executing the workflow
|
Delete the oldest 3 version of a package hosted from a repo not having access to package
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
owner: 'github'
|
owner: 'github'
|
||||||
repo: 'packages'
|
|
||||||
package-name: 'test-package'
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
num-old-versions-to-delete: 3
|
num-old-versions-to-delete: 3
|
||||||
token: ${{ secrets.GITHUB_PAT }}
|
token: ${{ secrets.GITHUB_PAT }}
|
||||||
```
|
```
|
||||||
@@ -269,28 +315,27 @@ This action deletes versions of a package from [GitHub Packages](https://github.
|
|||||||
|
|
||||||
### Delete oldest version of a package
|
### Delete oldest version of a package
|
||||||
|
|
||||||
To delete the oldest version of a package that is hosted in the same repo as the workflow the __package-name__ input is required.
|
To delete the oldest version of a package that is hosted, the __package-name__ input is required.
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
package-name: 'test-package'
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
```
|
```
|
||||||
|
|
||||||
To delete the oldest version of a package that is hosted in a different repo than the workflow the __owner__, __repo__, __package-name__, __token__ inputs are required.
|
To delete the oldest version of a package that is hosted from a repo not having access to package, the __owner__, __package-name__, __token__ inputs are required.
|
||||||
|
|
||||||
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
owner: 'github'
|
owner: 'github'
|
||||||
repo: 'packages'
|
|
||||||
package-name: 'test-package'
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.PAT }}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -298,30 +343,32 @@ This action deletes versions of a package from [GitHub Packages](https://github.
|
|||||||
|
|
||||||
### Delete a specific version of a package
|
### Delete a specific version of a package
|
||||||
|
|
||||||
To delete a specific version of a package that is hosted in the same repo as the workflow the __package-version-ids__ input is required.
|
To delete a specific version of a package that is hosted, the __package-version-ids__ input is required.
|
||||||
|
|
||||||
Package version ids can be retrieved via the [GitHub GraphQL API][api]
|
Package version ids can be retrieved via the [GitHub REST API][api]
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
package-version-ids: 'MDE0OlBhY2thZ2VWZXJzaW9uOTcyMDY3'
|
package-version-ids: 'MDE0OlBhY2thZ2VWZXJzaW9uOTcyMDY3'
|
||||||
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
```
|
```
|
||||||
|
|
||||||
To delete a specific version of a package that is hosted in a different repo than the workflow the __package-version-ids__ and __token__ inputs are required.
|
To delete a specific version of a package that is hosted from a repo not having access to package, the __package-version-ids__ and __token__ inputs are required.
|
||||||
|
|
||||||
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
Package version ids can be retrieved via the [GitHub REST API][api]
|
||||||
|
|
||||||
Package version ids can be retrieved via the [GitHub GraphQL API][api]
|
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
package-version-ids: 'MDE0OlBhY2thZ2VWZXJzaW9uOTcyMDY3'
|
package-version-ids: 'MDE0OlBhY2thZ2VWZXJzaW9uOTcyMDY3'
|
||||||
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.PAT }}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -329,30 +376,32 @@ This action deletes versions of a package from [GitHub Packages](https://github.
|
|||||||
|
|
||||||
### Delete multiple specific versions of a package
|
### Delete multiple specific versions of a package
|
||||||
|
|
||||||
To delete multiple specifc versions of a package that is hosted in the same repo as the workflow the __package-version-ids__ input is required.
|
To delete multiple specific versions of a package that is hosted, the __package-version-ids__ input is required.
|
||||||
|
|
||||||
The __package-version-ids__ input should be a comma separated string of package version ids. Package version ids can be retrieved via the [GitHub GraphQL API][api].
|
The __package-version-ids__ input should be a comma separated string of package version ids. Package version ids can be retrieved via the [GitHub REST API][api].
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
package-version-ids: 'MDE0OlBhY2thZ2VWZXJzaW9uOTcyMDY3, MDE0OlBhY2thZ2VWZXJzaW9uOTcyMzQ5, MDE0OlBhY2thZ2VWZXJzaW9uOTcyMzUw'
|
package-version-ids: 'MDE0OlBhY2thZ2VWZXJzaW9uOTcyMDY3, MDE0OlBhY2thZ2VWZXJzaW9uOTcyMzQ5, MDE0OlBhY2thZ2VWZXJzaW9uOTcyMzUw'
|
||||||
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
```
|
```
|
||||||
|
|
||||||
To delete multiple specifc versions of a package that is hosted in a repo other than the workflow the __package-version-ids__, __token__ inputs are required.
|
To delete multiple specific versions of a package that is hosted from a repo not having access to package, the __package-version-ids__, __token__ inputs are required.
|
||||||
|
|
||||||
The __package-version-ids__ input should be a comma separated string of package version ids. Package version ids can be retrieved via the [GitHub GraphQL API][api].
|
The __package-version-ids__ input should be a comma separated string of package version ids. Package version ids can be retrieved via the [GitHub REST API][api].
|
||||||
|
|
||||||
The [token][token] needs the delete packages and read packages scope. It is recommended [to store the token as a secret][secret]. In this example the [token][token] was stored as a secret named __GITHUB_PAT__.
|
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: actions/delete-package-versions@v2
|
- uses: actions/delete-package-versions@v4
|
||||||
with:
|
with:
|
||||||
package-version-ids: 'MDE0OlBhY2thZ2VWZXJzaW9uOTcyMDY3, MDE0OlBhY2thZ2VWZXJzaW9uOTcyMzQ5, MDE0OlBhY2thZ2VWZXJzaW9uOTcyMzUw'
|
package-version-ids: 'MDE0OlBhY2thZ2VWZXJzaW9uOTcyMDY3, MDE0OlBhY2thZ2VWZXJzaW9uOTcyMzQ5, MDE0OlBhY2thZ2VWZXJzaW9uOTcyMzUw'
|
||||||
|
package-name: 'test-package'
|
||||||
|
package-type: 'npm'
|
||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.PAT }}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -360,6 +409,6 @@ This action deletes versions of a package from [GitHub Packages](https://github.
|
|||||||
|
|
||||||
The scripts and documentation in this project are released under the [MIT License](https://github.com/actions/delete-package-versions/blob/main/LICENSE)
|
The scripts and documentation in this project are released under the [MIT License](https://github.com/actions/delete-package-versions/blob/main/LICENSE)
|
||||||
|
|
||||||
[api]: https://developer.github.com/v4/previews/#github-packages
|
[api]: https://docs.github.com/en/rest/packages
|
||||||
[token]: https://help.github.com/en/packages/publishing-and-managing-packages/about-github-packages#about-tokens
|
[token]: https://help.github.com/en/packages/publishing-and-managing-packages/about-github-packages#about-tokens
|
||||||
[secret]: https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets
|
[secret]: https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets
|
||||||
|
|||||||
@@ -1,43 +1,347 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
|
import {rest} from 'msw'
|
||||||
|
import {setupServer} from 'msw/node'
|
||||||
import {Input, InputParams} from '../src/input'
|
import {Input, InputParams} from '../src/input'
|
||||||
import {deleteVersions, getVersionIds} from '../src/delete'
|
import {deleteVersions, finalIds, RATE_LIMIT} from '../src/delete'
|
||||||
|
import {getMockedVersionsResponse} from './version/rest.mock'
|
||||||
|
import {RestEndpointMethodTypes} from '@octokit/plugin-rest-endpoint-methods/dist-types/generated/parameters-and-response-types'
|
||||||
|
|
||||||
describe.skip('index tests -- call graphql', () => {
|
type GetVersionsResponseData =
|
||||||
it('getVersionIds test -- get oldest version', done => {
|
RestEndpointMethodTypes['packages']['getAllPackageVersionsForPackageOwnedByUser']['response']['data']
|
||||||
const numVersions = 1
|
|
||||||
|
|
||||||
getVersionIds(getInput({numOldVersionsToDelete: numVersions})).subscribe(
|
describe('index tests -- call rest', () => {
|
||||||
ids => {
|
let server = setupServer()
|
||||||
expect(ids.length).toBeLessThanOrEqual(numVersions)
|
|
||||||
done()
|
beforeEach(() => {
|
||||||
}
|
server = setupServer()
|
||||||
)
|
server.listen()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('getVersionIds test -- get oldest 3 versions', done => {
|
afterEach(() => {
|
||||||
const numVersions = 3
|
server.close()
|
||||||
|
|
||||||
getVersionIds(getInput({numOldVersionsToDelete: numVersions})).subscribe(
|
|
||||||
ids => {
|
|
||||||
expect(ids.length).toBeLessThanOrEqual(numVersions)
|
|
||||||
done()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('getVersionIds test -- supplied package version id', done => {
|
it('finalIds test - supplied package version id', done => {
|
||||||
const suppliedIds = [
|
const suppliedIds = ['123', '456', '789']
|
||||||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
finalIds(getInput({packageVersionIds: suppliedIds})).subscribe(ids => {
|
||||||
'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
|
expect(ids).toStrictEqual(suppliedIds)
|
||||||
'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'
|
|
||||||
]
|
|
||||||
|
|
||||||
getVersionIds(getInput({packageVersionIds: suppliedIds})).subscribe(ids => {
|
|
||||||
expect(ids).toBe(suppliedIds)
|
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('deleteVersions test -- missing token', done => {
|
it('finalIDs test - success', done => {
|
||||||
|
const numVersions = 10
|
||||||
|
let apiCalled = 0
|
||||||
|
|
||||||
|
const versions = getMockedVersionsResponse(numVersions)
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
apiCalled++
|
||||||
|
return res(ctx.status(200), ctx.json(versions))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
finalIds(getInput()).subscribe(ids => {
|
||||||
|
expect(apiCalled).toBe(1)
|
||||||
|
expect(ids.length).toBe(numVersions)
|
||||||
|
for (let i = 0; i < numVersions; i++) {
|
||||||
|
expect(ids[i]).toBe(versions[i].id.toString())
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('finalIDs test - success - GHES', done => {
|
||||||
|
process.env.GITHUB_API_URL = 'https://github.someghesinstance.com/api/v3'
|
||||||
|
|
||||||
|
const numVersions = 10
|
||||||
|
let apiCalled = 0
|
||||||
|
|
||||||
|
const versions = getMockedVersionsResponse(numVersions)
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://github.someghesinstance.com/api/v3/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
apiCalled++
|
||||||
|
return res(ctx.status(200), ctx.json(versions))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
finalIds(getInput()).subscribe(ids => {
|
||||||
|
expect(apiCalled).toBe(1)
|
||||||
|
expect(ids.length).toBe(numVersions)
|
||||||
|
for (let i = 0; i < numVersions; i++) {
|
||||||
|
expect(ids[i]).toBe(versions[i].id.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
delete process.env.GITHUB_API_URL
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('finalIDs test - success - pagination', done => {
|
||||||
|
const numVersions = RATE_LIMIT * 2
|
||||||
|
let apiCalled = 0
|
||||||
|
|
||||||
|
const versions = getMockedVersionsResponse(numVersions)
|
||||||
|
|
||||||
|
const firstPage = versions.slice(0, RATE_LIMIT)
|
||||||
|
const secondPage = versions.slice(RATE_LIMIT)
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
apiCalled++
|
||||||
|
const page = req.url.searchParams.get('page')
|
||||||
|
if (page === '1') {
|
||||||
|
return res(ctx.status(200), ctx.json(firstPage))
|
||||||
|
} else if (page === '2') {
|
||||||
|
return res(ctx.status(200), ctx.json(secondPage))
|
||||||
|
} else {
|
||||||
|
return res(ctx.status(200), ctx.json([]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
finalIds(getInput()).subscribe(ids => {
|
||||||
|
expect(apiCalled).toBe(3) // 2 full pages + 1 empty page
|
||||||
|
// never returns more than RATE_LIMIT versions
|
||||||
|
expect(ids.length).toBe(RATE_LIMIT)
|
||||||
|
for (let i = 0; i < RATE_LIMIT; i++) {
|
||||||
|
expect(ids[i]).toBe(versions[i].id.toString())
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('finalIDs test - success - sorting accross pages', done => {
|
||||||
|
const numVersions = RATE_LIMIT * 2
|
||||||
|
let apiCalled = 0
|
||||||
|
|
||||||
|
// versions is in ascending order of created_at
|
||||||
|
const versions = getMockedVersionsResponse(numVersions)
|
||||||
|
|
||||||
|
// return newer versions on first page to test sorting
|
||||||
|
const firstPage = versions.slice(RATE_LIMIT).reverse()
|
||||||
|
const secondPage = versions.slice(0, RATE_LIMIT).reverse()
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
apiCalled++
|
||||||
|
const page = req.url.searchParams.get('page')
|
||||||
|
if (page === '1') {
|
||||||
|
return res(ctx.status(200), ctx.json(firstPage))
|
||||||
|
} else if (page === '2') {
|
||||||
|
return res(ctx.status(200), ctx.json(secondPage))
|
||||||
|
} else {
|
||||||
|
return res(ctx.status(200), ctx.json([]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
finalIds(getInput()).subscribe(ids => {
|
||||||
|
expect(apiCalled).toBe(3) // 2 full pages + 1 empty page
|
||||||
|
expect(ids.length).toBe(RATE_LIMIT)
|
||||||
|
for (let i = 0; i < RATE_LIMIT; i++) {
|
||||||
|
expect(ids[i]).toBe(versions[i].id.toString())
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('finalIds test - do not delete more than numOldVersionsToDelete', done => {
|
||||||
|
const numVersions = 50
|
||||||
|
let apiCalled = 0
|
||||||
|
|
||||||
|
const versions = getMockedVersionsResponse(numVersions)
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
apiCalled++
|
||||||
|
return res(ctx.status(200), ctx.json(versions))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
const numOldVersionsToDelete = 10
|
||||||
|
|
||||||
|
finalIds(getInput({numOldVersionsToDelete})).subscribe(ids => {
|
||||||
|
expect(apiCalled).toBe(1)
|
||||||
|
expect(ids.length).toBe(numOldVersionsToDelete)
|
||||||
|
for (let i = 0; i < numOldVersionsToDelete; i++) {
|
||||||
|
expect(ids[i]).toBe(versions[i].id.toString())
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('finalIds test - keep minVersionsToKeep', done => {
|
||||||
|
const numVersions = 50
|
||||||
|
let apiCalled = 0
|
||||||
|
|
||||||
|
const versions = getMockedVersionsResponse(numVersions)
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
apiCalled++
|
||||||
|
return res(ctx.status(200), ctx.json(versions))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
const minVersionsToKeep = 10
|
||||||
|
|
||||||
|
finalIds(getInput({minVersionsToKeep})).subscribe(ids => {
|
||||||
|
expect(apiCalled).toBe(1)
|
||||||
|
expect(ids.length).toBe(numVersions - minVersionsToKeep)
|
||||||
|
for (let i = 0; i < numVersions - minVersionsToKeep; i++) {
|
||||||
|
expect(ids[i]).toBe(versions[i].id.toString())
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('finalIds test - delete only prerelease versions with minVersionsToKeep', done => {
|
||||||
|
const numVersions = 50
|
||||||
|
let apiCalled = 0
|
||||||
|
|
||||||
|
const versions = getMockedVersionsResponse(numVersions)
|
||||||
|
// make half versions prerelease
|
||||||
|
for (let i = 0; i < numVersions; i++) {
|
||||||
|
if (i % 2 === 0) {
|
||||||
|
versions[i].name += '-alpha'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
apiCalled++
|
||||||
|
return res(ctx.status(200), ctx.json(versions))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
const toDelete = numVersions / 2 - 10
|
||||||
|
|
||||||
|
finalIds(
|
||||||
|
getInput({
|
||||||
|
ignoreVersions: RegExp('^(0|[1-9]\\d*)((\\.(0|[1-9]\\d*))*)$'),
|
||||||
|
minVersionsToKeep: 10
|
||||||
|
})
|
||||||
|
).subscribe(ids => {
|
||||||
|
expect(apiCalled).toBe(1)
|
||||||
|
expect(ids.length).toBe(toDelete)
|
||||||
|
for (let i = 0; i < toDelete; i++) {
|
||||||
|
expect(ids[i]).toBe(versions[i * 2].id.toString())
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('finalIds test - delete only untagged versions with minVersionsToKeep', done => {
|
||||||
|
const numVersions = 50
|
||||||
|
const numTaggedVersions = 20
|
||||||
|
const numUntaggedVersions = numVersions - numTaggedVersions
|
||||||
|
|
||||||
|
const taggedVersions = getMockedVersionsResponse(
|
||||||
|
numTaggedVersions,
|
||||||
|
0,
|
||||||
|
'container',
|
||||||
|
true
|
||||||
|
)
|
||||||
|
const untaggedVersions = getMockedVersionsResponse(
|
||||||
|
numUntaggedVersions,
|
||||||
|
numTaggedVersions,
|
||||||
|
'container',
|
||||||
|
false
|
||||||
|
)
|
||||||
|
const versions = taggedVersions.concat(untaggedVersions)
|
||||||
|
|
||||||
|
let apiCalled = 0
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/container/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
apiCalled++
|
||||||
|
return res(ctx.status(200), ctx.json(versions))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
finalIds(
|
||||||
|
getInput({
|
||||||
|
minVersionsToKeep: 10,
|
||||||
|
deleteUntaggedVersions: 'true',
|
||||||
|
packageType: 'container'
|
||||||
|
})
|
||||||
|
).subscribe(ids => {
|
||||||
|
expect(apiCalled).toBe(1)
|
||||||
|
expect(ids.length).toBe(numUntaggedVersions - 10)
|
||||||
|
for (let i = 0; i < numUntaggedVersions - 10; i++) {
|
||||||
|
expect(ids[i]).toBe(untaggedVersions[i].id.toString())
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('finalIds test - no versions deleted if API error even once', done => {
|
||||||
|
const numVersions = RATE_LIMIT * 2
|
||||||
|
let apiCalled = 0
|
||||||
|
|
||||||
|
const versions = getMockedVersionsResponse(numVersions)
|
||||||
|
|
||||||
|
const firstPage = versions.slice(0, RATE_LIMIT)
|
||||||
|
const secondPage = versions.slice(RATE_LIMIT)
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
apiCalled++
|
||||||
|
const page = req.url.searchParams.get('page')
|
||||||
|
if (page === '1') {
|
||||||
|
return res(ctx.status(200), ctx.json(firstPage))
|
||||||
|
} else if (page === '2') {
|
||||||
|
return res(ctx.status(500), ctx.json([]))
|
||||||
|
} else {
|
||||||
|
return res(ctx.status(200), ctx.json([]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
finalIds(getInput()).subscribe(
|
||||||
|
() => {
|
||||||
|
done.fail('should not complete')
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
expect(apiCalled).toBe(2) // 1 full page + 1 error page
|
||||||
|
expect(err).toBeTruthy()
|
||||||
|
expect(err).toContain('get versions API failed.')
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('deleteVersions test - missing token', done => {
|
||||||
deleteVersions(getInput({token: ''})).subscribe({
|
deleteVersions(getInput({token: ''})).subscribe({
|
||||||
error: err => {
|
error: err => {
|
||||||
expect(err).toBeTruthy()
|
expect(err).toBeTruthy()
|
||||||
@@ -47,7 +351,7 @@ describe.skip('index tests -- call graphql', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('deleteVersions test -- missing packageName', done => {
|
it('deleteVersions test - missing packageName', done => {
|
||||||
deleteVersions(getInput({packageName: ''})).subscribe({
|
deleteVersions(getInput({packageName: ''})).subscribe({
|
||||||
error: err => {
|
error: err => {
|
||||||
expect(err).toBeTruthy()
|
expect(err).toBeTruthy()
|
||||||
@@ -57,40 +361,123 @@ describe.skip('index tests -- call graphql', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it.skip('deleteVersions test -- delete oldest version', done => {
|
it('deleteVersions test - missing packageType', done => {
|
||||||
deleteVersions(
|
deleteVersions(getInput({packageType: ''})).subscribe({
|
||||||
getInput({numOldVersionsToDelete: 2, minVersionsToKeep: 1})
|
error: err => {
|
||||||
).subscribe(isSuccess => {
|
expect(err).toBeTruthy()
|
||||||
expect(isSuccess).toBe(true)
|
done()
|
||||||
|
},
|
||||||
|
complete: async () => done.fail('no error thrown')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('deleteVersions test - zero numOldVersionsToDelete', done => {
|
||||||
|
deleteVersions(getInput({numOldVersionsToDelete: 0})).subscribe(result => {
|
||||||
|
expect(result).toBe(true)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it.skip('deleteVersions test -- delete 3 oldest versions', done => {
|
it('deleteVersions test - success complete flow', done => {
|
||||||
deleteVersions(
|
const numVersions = 10
|
||||||
getInput({numOldVersionsToDelete: 3, minVersionsToKeep: 1})
|
let getApiCalled = 0
|
||||||
).subscribe(isSuccess => {
|
let deleteApiCalled = 0
|
||||||
expect(isSuccess).toBe(true)
|
|
||||||
done()
|
const versions = getMockedVersionsResponse(numVersions)
|
||||||
})
|
const versionsDeleted: string[] = []
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
getApiCalled++
|
||||||
|
return res(ctx.status(200), ctx.json(versions))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.delete(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions/:versionId',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
deleteApiCalled++
|
||||||
|
versionsDeleted.push(req.params.versionId as string)
|
||||||
|
return res(ctx.status(204))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
deleteVersions(getInput())
|
||||||
|
.subscribe(result => {
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
.add(() => {
|
||||||
|
expect(getApiCalled).toBe(1)
|
||||||
|
expect(deleteApiCalled).toBe(numVersions)
|
||||||
|
for (let i = 0; i < numVersions; i++) {
|
||||||
|
expect(versionsDeleted[i]).toBe(versions[i].id.toString())
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('deleteVersions test -- keep 5 versions', done => {
|
it('deleteVersions test - success complete flow - GHES', done => {
|
||||||
deleteVersions(getInput({minVersionsToKeep: 5})).subscribe(isSuccess => {
|
process.env.GITHUB_API_URL = 'https://github.someghesinstance.com/api/v3'
|
||||||
expect(isSuccess).toBe(true)
|
|
||||||
done()
|
const numVersions = 10
|
||||||
})
|
let getApiCalled = 0
|
||||||
|
let deleteApiCalled = 0
|
||||||
|
|
||||||
|
const versions = getMockedVersionsResponse(numVersions)
|
||||||
|
const versionsDeleted: string[] = []
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://github.someghesinstance.com/api/v3/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
getApiCalled++
|
||||||
|
return res(ctx.status(200), ctx.json(versions))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.delete(
|
||||||
|
'https://github.someghesinstance.com/api/v3/users/test-owner/packages/npm/test-package/versions/:versionId',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
deleteApiCalled++
|
||||||
|
versionsDeleted.push(req.params.versionId as string)
|
||||||
|
return res(ctx.status(204))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
deleteVersions(getInput())
|
||||||
|
.subscribe(result => {
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
.add(() => {
|
||||||
|
expect(getApiCalled).toBe(1)
|
||||||
|
expect(deleteApiCalled).toBe(numVersions)
|
||||||
|
for (let i = 0; i < numVersions; i++) {
|
||||||
|
expect(versionsDeleted[i]).toBe(versions[i].id.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
delete process.env.GITHUB_API_URL
|
||||||
|
done()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const defaultInput: InputParams = {
|
const defaultInput: InputParams = {
|
||||||
packageVersionIds: [],
|
packageVersionIds: [],
|
||||||
owner: 'namratajha',
|
owner: 'test-owner',
|
||||||
repo: 'only-pkg',
|
packageName: 'test-package',
|
||||||
packageName: 'onlypkg.maven',
|
packageType: 'npm',
|
||||||
numOldVersionsToDelete: 1,
|
numOldVersionsToDelete: RATE_LIMIT,
|
||||||
minVersionsToKeep: 1,
|
minVersionsToKeep: -1,
|
||||||
token: process.env.GITHUB_TOKEN as string
|
ignoreVersions: RegExp('^$'),
|
||||||
|
token: 'test-token'
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInput(params?: InputParams): Input {
|
function getInput(params?: InputParams): Input {
|
||||||
|
|||||||
@@ -1,25 +1,179 @@
|
|||||||
|
import {rest} from 'msw'
|
||||||
|
import {setupServer} from 'msw/node'
|
||||||
import {deletePackageVersion, deletePackageVersions} from '../../src/version'
|
import {deletePackageVersion, deletePackageVersions} from '../../src/version'
|
||||||
|
|
||||||
const githubToken = process.env.GITHUB_TOKEN as string
|
describe('delete tests - mock rest', () => {
|
||||||
|
let server = setupServer()
|
||||||
|
|
||||||
describe.skip('delete tests', () => {
|
beforeEach(() => {
|
||||||
it('deletePackageVersion', async () => {
|
server = setupServer()
|
||||||
const response = await deletePackageVersion(
|
server.listen()
|
||||||
'MDE0OlBhY2thZ2VWZXJzaW9uNjg5OTU1',
|
|
||||||
githubToken
|
|
||||||
).toPromise()
|
|
||||||
expect(response).toBe(true)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('deletePackageVersions', async () => {
|
afterEach(() => {
|
||||||
const response = await deletePackageVersions(
|
server.close()
|
||||||
[
|
})
|
||||||
'MDE0OlBhY2thZ2VWZXJzaW9uNjk4Mjc0',
|
|
||||||
'MDE0OlBhY2thZ2VWZXJzaW9uNjk4Mjcx',
|
it('deletePackageVersion', done => {
|
||||||
'MDE0OlBhY2thZ2VWZXJzaW9uNjk4MjY3'
|
server.use(
|
||||||
],
|
rest.delete(
|
||||||
githubToken
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions/123',
|
||||||
).toPromise()
|
(req, res, ctx) => {
|
||||||
expect(response).toBe(true)
|
return res(ctx.status(204))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
deletePackageVersion(
|
||||||
|
'123',
|
||||||
|
'test-owner',
|
||||||
|
'test-package',
|
||||||
|
'npm',
|
||||||
|
'test-token'
|
||||||
|
).subscribe(result => {
|
||||||
|
expect(result).toBe(true)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('deletePackageVersions', done => {
|
||||||
|
let success = 0
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.delete(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions/*',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
return res(ctx.status(204))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
deletePackageVersions(
|
||||||
|
['123', '456', '789'],
|
||||||
|
'test-owner',
|
||||||
|
'test-package',
|
||||||
|
'npm',
|
||||||
|
'test-token'
|
||||||
|
)
|
||||||
|
.subscribe(
|
||||||
|
result => {
|
||||||
|
expect(result).toBe(true)
|
||||||
|
success++
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
// should not get here
|
||||||
|
done.fail(err)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.add(() => {
|
||||||
|
expect(success).toBe(3)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('deletePackageVersions - GHES', done => {
|
||||||
|
process.env.GITHUB_API_URL = 'https://github.someghesinstance.com/api/v3'
|
||||||
|
|
||||||
|
let success = 0
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.delete(
|
||||||
|
'https://github.someghesinstance.com/api/v3/users/test-owner/packages/npm/test-package/versions/*',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
return res(ctx.status(204))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
deletePackageVersions(
|
||||||
|
['123', '456', '789'],
|
||||||
|
'test-owner',
|
||||||
|
'test-package',
|
||||||
|
'npm',
|
||||||
|
'test-token'
|
||||||
|
)
|
||||||
|
.subscribe(
|
||||||
|
result => {
|
||||||
|
expect(result).toBe(true)
|
||||||
|
success++
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
// should not get here
|
||||||
|
done.fail(err)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.add(() => {
|
||||||
|
expect(success).toBe(3)
|
||||||
|
|
||||||
|
delete process.env.GITHUB_API_URL
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('deletePackageVersion - API error', done => {
|
||||||
|
server.use(
|
||||||
|
rest.delete(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions/123',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
return res(ctx.status(500))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
deletePackageVersion(
|
||||||
|
'123',
|
||||||
|
'test-owner',
|
||||||
|
'test-package',
|
||||||
|
'npm',
|
||||||
|
'test-token'
|
||||||
|
).subscribe(
|
||||||
|
() => {
|
||||||
|
done.fail('should not get here.')
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
expect(err).toContain('delete version API failed.')
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('deletePackageVersions - API error for some versions', done => {
|
||||||
|
let success = 0
|
||||||
|
let failed = 0
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.delete(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions/:versionId',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
if (req.params.versionId === '456') {
|
||||||
|
return res(ctx.status(500))
|
||||||
|
}
|
||||||
|
return res(ctx.status(204))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
deletePackageVersions(
|
||||||
|
['123', '456', '789'],
|
||||||
|
'test-owner',
|
||||||
|
'test-package',
|
||||||
|
'npm',
|
||||||
|
'test-token'
|
||||||
|
)
|
||||||
|
.subscribe(
|
||||||
|
result => {
|
||||||
|
expect(result).toBe(true)
|
||||||
|
success++
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
expect(err).toContain('delete version API failed.')
|
||||||
|
failed++
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.add(() => {
|
||||||
|
expect(success).toBe(2)
|
||||||
|
expect(failed).toBe(1)
|
||||||
|
done()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,68 +1,200 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
import {rest} from 'msw'
|
||||||
// @ts-ignore
|
import {setupServer} from 'msw/node'
|
||||||
import {mockOldestQueryResponse} from './graphql.mock'
|
|
||||||
import {
|
import {
|
||||||
getOldestVersions as _getOldestVersions,
|
getOldestVersions as _getOldestVersions,
|
||||||
VersionInfo
|
RestQueryInfo
|
||||||
} from '../../src/version'
|
} from '../../src/version'
|
||||||
import {Observable} from 'rxjs'
|
import {Observable} from 'rxjs'
|
||||||
|
import {getMockedVersionsResponse} from './rest.mock'
|
||||||
|
import {RATE_LIMIT} from '../../src/delete'
|
||||||
|
|
||||||
describe.skip('get versions tests -- call graphql', () => {
|
describe('get versions tests -- mock rest', () => {
|
||||||
it('getOldestVersions -- succeeds', done => {
|
let server = setupServer()
|
||||||
const numVersions = 1
|
|
||||||
|
|
||||||
getOldestVersions({numVersions}).subscribe(versions => {
|
beforeEach(() => {
|
||||||
expect(versions.length).toBe(numVersions)
|
server = setupServer()
|
||||||
done()
|
server.listen()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('getOldestVersions -- fails for invalid repo', done => {
|
afterEach(() => {
|
||||||
getOldestVersions({repo: 'actions-testin'}).subscribe({
|
server.close()
|
||||||
error: err => {
|
|
||||||
expect(err).toBeTruthy()
|
|
||||||
done()
|
|
||||||
},
|
|
||||||
complete: async () => done.fail('no error thrown')
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
|
||||||
|
|
||||||
describe('get versions tests -- mock graphql', () => {
|
|
||||||
it('getOldestVersions -- success', done => {
|
it('getOldestVersions -- success', done => {
|
||||||
const numVersions = 5
|
const numVersions = RATE_LIMIT
|
||||||
mockOldestQueryResponse(numVersions)
|
const resp = getMockedVersionsResponse(numVersions)
|
||||||
|
|
||||||
getOldestVersions({numVersions}).subscribe(versions => {
|
server.use(
|
||||||
expect(versions.length).toBe(numVersions)
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
return res(ctx.status(200), ctx.json(resp))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
getOldestVersions({numVersions}).subscribe(result => {
|
||||||
|
expect(result.versions.length).toBe(numVersions)
|
||||||
|
for (let i = 0; i < numVersions; i++) {
|
||||||
|
expect(result.versions[i].id).toBe(resp[i].id)
|
||||||
|
expect(result.versions[i].version).toBe(resp[i].name)
|
||||||
|
expect(result.versions[i].created_at).toBe(resp[i].created_at)
|
||||||
|
}
|
||||||
|
expect(result.paginate).toBe(true)
|
||||||
|
expect(result.totalCount).toBe(numVersions)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('getOldestVersions -- success - GHES', done => {
|
||||||
|
const numVersions = RATE_LIMIT
|
||||||
|
const resp = getMockedVersionsResponse(numVersions)
|
||||||
|
|
||||||
|
// set GITHUB_API_URL to a different base url
|
||||||
|
process.env.GITHUB_API_URL = 'https://github.someghesinstance.com/api/v3'
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://github.someghesinstance.com/api/v3/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
return res(ctx.status(200), ctx.json(resp))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
getOldestVersions({numVersions}).subscribe(result => {
|
||||||
|
expect(result.versions.length).toBe(numVersions)
|
||||||
|
for (let i = 0; i < numVersions; i++) {
|
||||||
|
expect(result.versions[i].id).toBe(resp[i].id)
|
||||||
|
expect(result.versions[i].version).toBe(resp[i].name)
|
||||||
|
expect(result.versions[i].created_at).toBe(resp[i].created_at)
|
||||||
|
}
|
||||||
|
expect(result.paginate).toBe(true)
|
||||||
|
expect(result.totalCount).toBe(numVersions)
|
||||||
|
|
||||||
|
delete process.env.GITHUB_API_URL
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('getOldestVersions -- success - container tagged versions', done => {
|
||||||
|
const numVersions = 6
|
||||||
|
const numTaggedVersions = 3
|
||||||
|
const numUntaggedVersions = numVersions - numTaggedVersions
|
||||||
|
|
||||||
|
const respTagged = getMockedVersionsResponse(
|
||||||
|
numTaggedVersions,
|
||||||
|
0,
|
||||||
|
'container',
|
||||||
|
true
|
||||||
|
)
|
||||||
|
const respUntagged = getMockedVersionsResponse(
|
||||||
|
numUntaggedVersions,
|
||||||
|
numTaggedVersions,
|
||||||
|
'container',
|
||||||
|
false
|
||||||
|
)
|
||||||
|
const resp = respTagged.concat(respUntagged)
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/container/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
return res(ctx.status(200), ctx.json(resp))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
getOldestVersions({numVersions, packageType: 'container'}).subscribe(
|
||||||
|
result => {
|
||||||
|
expect(result.versions.length).toBe(numVersions)
|
||||||
|
for (let i = 0; i < numVersions; i++) {
|
||||||
|
expect(result.versions[i].id).toBe(resp[i].id)
|
||||||
|
expect(result.versions[i].version).toBe(resp[i].name)
|
||||||
|
expect(result.versions[i].created_at).toBe(resp[i].created_at)
|
||||||
|
if (i < numTaggedVersions) {
|
||||||
|
expect(result.versions[i].tagged).toBe(true)
|
||||||
|
} else {
|
||||||
|
expect(result.versions[i].tagged).toBe(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(result.paginate).toBe(true)
|
||||||
|
expect(result.totalCount).toBe(numVersions)
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('getOldestVersions -- paginate is false when fetched versions is less than page size', done => {
|
||||||
|
const numVersions = 5
|
||||||
|
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
return res(
|
||||||
|
ctx.status(200),
|
||||||
|
ctx.json(getMockedVersionsResponse(numVersions))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// In the call numVersions is set to RATE_LIMIT, but the response has only 5 versions.
|
||||||
|
getOldestVersions().subscribe(result => {
|
||||||
|
expect(result.paginate).toBe(false)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('getOldestVersions -- API error', done => {
|
||||||
|
server.use(
|
||||||
|
rest.get(
|
||||||
|
'https://api.github.com/users/test-owner/packages/npm/test-package/versions',
|
||||||
|
(req, res, ctx) => {
|
||||||
|
return res(ctx.status(500))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
getOldestVersions().subscribe(
|
||||||
|
() => {
|
||||||
|
done.fail('should not get here.')
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
expect(err).toContain('get versions API failed.')
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
interface Params {
|
interface Params {
|
||||||
owner?: string
|
owner?: string
|
||||||
repo?: string
|
|
||||||
packageName?: string
|
packageName?: string
|
||||||
|
packageType?: string
|
||||||
numVersions?: number
|
numVersions?: number
|
||||||
|
page?: number
|
||||||
token?: string
|
token?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultParams = {
|
const defaultParams = {
|
||||||
owner: 'namratajha',
|
owner: 'test-owner',
|
||||||
repo: 'only-pkg',
|
packageName: 'test-package',
|
||||||
packageName: 'onlypkg.maven',
|
packageType: 'npm',
|
||||||
numVersions: 3,
|
numVersions: RATE_LIMIT,
|
||||||
token: process.env.GITHUB_TOKEN as string
|
page: 1,
|
||||||
|
token: 'test-token'
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOldestVersions(params?: Params): Observable<VersionInfo[]> {
|
function getOldestVersions(params?: Params): Observable<RestQueryInfo> {
|
||||||
const p: Required<Params> = {...defaultParams, ...params}
|
const p: Required<Params> = {...defaultParams, ...params}
|
||||||
return _getOldestVersions(
|
return _getOldestVersions(
|
||||||
p.owner,
|
p.owner,
|
||||||
p.repo,
|
|
||||||
p.packageName,
|
p.packageName,
|
||||||
|
p.packageType,
|
||||||
p.numVersions,
|
p.numVersions,
|
||||||
|
p.page,
|
||||||
p.token
|
p.token
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
import {
|
|
||||||
GraphQlQueryResponseData,
|
|
||||||
RequestParameters
|
|
||||||
} from '@octokit/graphql/dist-types/types'
|
|
||||||
|
|
||||||
import * as Graphql from '../../src/version/graphql'
|
|
||||||
import {GetVersionsQueryResponse} from '../../src/version'
|
|
||||||
|
|
||||||
export function getMockedOldestQueryResponse(
|
|
||||||
numVersions: number
|
|
||||||
): GetVersionsQueryResponse {
|
|
||||||
const versions = []
|
|
||||||
|
|
||||||
for (let i = 1; i <= numVersions; ++i) {
|
|
||||||
versions.push({
|
|
||||||
node: {
|
|
||||||
id: i.toString(),
|
|
||||||
version: `${i}.0.0`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
repository: {
|
|
||||||
packages: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
name: 'test',
|
|
||||||
versions: {
|
|
||||||
edges: versions.reverse()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mockOldestQueryResponse(
|
|
||||||
numVersions: number
|
|
||||||
) {
|
|
||||||
const response = new Promise((resolve) => {
|
|
||||||
resolve(getMockedOldestQueryResponse(numVersions))
|
|
||||||
}) as Promise<GraphQlQueryResponseData>
|
|
||||||
jest.spyOn(Graphql, 'graphql').mockImplementation(
|
|
||||||
(token: string, query: string, parameters: RequestParameters) => response)
|
|
||||||
}
|
|
||||||
45
__tests__/version/rest.mock.ts
Normal file
45
__tests__/version/rest.mock.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import {RestEndpointMethodTypes} from '@octokit/plugin-rest-endpoint-methods/dist-types/generated/parameters-and-response-types'
|
||||||
|
|
||||||
|
type GetVersionsResponseData =
|
||||||
|
RestEndpointMethodTypes['packages']['getAllPackageVersionsForPackageOwnedByUser']['response']['data']
|
||||||
|
type PackageType =
|
||||||
|
RestEndpointMethodTypes['packages']['getAllPackageVersionsForPackageOwnedByUser']['parameters']['package_type']
|
||||||
|
|
||||||
|
export function getMockedVersionsResponse(
|
||||||
|
numVersions: number,
|
||||||
|
offset = 0,
|
||||||
|
packageType = 'npm',
|
||||||
|
tagged = false
|
||||||
|
): GetVersionsResponseData {
|
||||||
|
const versions: GetVersionsResponseData = []
|
||||||
|
for (let i = 1 + offset; i <= numVersions + offset; ++i) {
|
||||||
|
const created_at = new Date()
|
||||||
|
created_at.setUTCFullYear(2000 + Number(i), 1, 1)
|
||||||
|
let version = {
|
||||||
|
id: i,
|
||||||
|
name: `${i}.0.0`,
|
||||||
|
url: '',
|
||||||
|
created_at: created_at.toUTCString(),
|
||||||
|
package_html_url: '',
|
||||||
|
updated_at: '',
|
||||||
|
metadata: {
|
||||||
|
package_type: packageType as PackageType
|
||||||
|
}
|
||||||
|
} as GetVersionsResponseData[0]
|
||||||
|
|
||||||
|
if (packageType === 'container' && tagged) {
|
||||||
|
version = {
|
||||||
|
...version,
|
||||||
|
metadata: {
|
||||||
|
package_type: packageType as PackageType,
|
||||||
|
container: {
|
||||||
|
tags: [`latest${i}`] as string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
versions.push(version)
|
||||||
|
}
|
||||||
|
return versions
|
||||||
|
}
|
||||||
34
action.yml
34
action.yml
@@ -15,17 +15,15 @@ inputs:
|
|||||||
Defaults to the owner of the repo running the action.
|
Defaults to the owner of the repo running the action.
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
repo:
|
|
||||||
description: >
|
|
||||||
Repo containing the package version to delete.
|
|
||||||
Defaults to the repo running the action.
|
|
||||||
required: false
|
|
||||||
|
|
||||||
package-name:
|
package-name:
|
||||||
description: >
|
description: >
|
||||||
Name of the package containing the version to delete.
|
Name of the package containing the version to delete.
|
||||||
Required if dynamically deleting oldest versions.
|
required: true
|
||||||
required: false
|
|
||||||
|
package-type:
|
||||||
|
description: >
|
||||||
|
Type of package. Can be one of container, maven, npm, nuget, or rubygems.
|
||||||
|
required: true
|
||||||
|
|
||||||
num-old-versions-to-delete:
|
num-old-versions-to-delete:
|
||||||
description: >
|
description: >
|
||||||
@@ -37,9 +35,10 @@ inputs:
|
|||||||
min-versions-to-keep:
|
min-versions-to-keep:
|
||||||
description: >
|
description: >
|
||||||
Number of versions to keep starting with the latest version
|
Number of versions to keep starting with the latest version
|
||||||
Defaults to 0.
|
By default keeps no version.
|
||||||
|
To delete all versions set this as 0.
|
||||||
required: false
|
required: false
|
||||||
default: "0"
|
default: "-1"
|
||||||
|
|
||||||
ignore-versions:
|
ignore-versions:
|
||||||
description: >
|
description: >
|
||||||
@@ -50,12 +49,21 @@ inputs:
|
|||||||
|
|
||||||
delete-only-pre-release-versions:
|
delete-only-pre-release-versions:
|
||||||
description: >
|
description: >
|
||||||
Deletes only pre-release versions upto. The number of pre-release versions to keep can be specified by min-versions-to-keep.
|
Deletes only pre-release versions. The number of pre-release versions to keep can be specified by min-versions-to-keep.
|
||||||
When this is set num-old-versions-to-delete and ignore-versions will not be taken into account.
|
When this is set num-old-versions-to-delete and ignore-versions will not be taken into account.
|
||||||
By default this is set to false
|
By default this is set to false
|
||||||
required: false
|
required: false
|
||||||
default: "false"
|
default: "false"
|
||||||
|
|
||||||
|
delete-only-untagged-versions:
|
||||||
|
description: >
|
||||||
|
Deletes only untagged versions in case of a container package. Does not work for other package types.
|
||||||
|
The number of untagged versions to keep can be specified by min-versions-to-keep.
|
||||||
|
When this is set num-old-versions-to-delete will not be taken into account.
|
||||||
|
By default this is set to false
|
||||||
|
required: false
|
||||||
|
default: "false"
|
||||||
|
|
||||||
token:
|
token:
|
||||||
description: >
|
description: >
|
||||||
Token with the necessary scopes to delete package versions.
|
Token with the necessary scopes to delete package versions.
|
||||||
@@ -66,9 +74,9 @@ inputs:
|
|||||||
default: ${{ github.token }}
|
default: ${{ github.token }}
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: node12
|
using: node16
|
||||||
main: dist/index.js
|
main: dist/index.js
|
||||||
|
|
||||||
branding:
|
branding:
|
||||||
icon: package
|
icon: package
|
||||||
color: blue
|
color: blue
|
||||||
|
|||||||
19264
dist/index.js
vendored
19264
dist/index.js
vendored
File diff suppressed because one or more lines are too long
19890
package-lock.json
generated
19890
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
@@ -7,9 +7,10 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"format": "prettier --write **/*.ts",
|
"format": "prettier --write **/*.ts",
|
||||||
"format-check": "prettier --check **/*.ts",
|
"format-check": "prettier --check **/*.ts",
|
||||||
"lint": "eslint src/**/*.ts",
|
"lint": "eslint src/**/*.ts --fix",
|
||||||
|
"lint-check": "eslint src/**/*.ts",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"build": "npm run format-check && npm run lint && npm run test && tsc",
|
"build": "npm run format-check && npm run lint-check && npm run test && tsc",
|
||||||
"pack": "rm -rf ./lib ./dist && npm run build && ncc build"
|
"pack": "rm -rf ./lib ./dist && npm run build && ncc build"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -24,23 +25,24 @@
|
|||||||
"author": "YourNameOrOrganization",
|
"author": "YourNameOrOrganization",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.6.0",
|
"@actions/core": "^1.9.1",
|
||||||
"@actions/github": "^2.1.1",
|
"@actions/github": "^2.1.1",
|
||||||
|
"@octokit/rest": "^19.0.5",
|
||||||
"rxjs": "^6.5.4"
|
"rxjs": "^6.5.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^24.0.23",
|
"@types/jest": "^27.5.2",
|
||||||
"@types/node": "^12.7.12",
|
"@types/node": "^18.11.18",
|
||||||
"@typescript-eslint/parser": "^2.8.0",
|
"@typescript-eslint/parser": "^5.47.1",
|
||||||
"@vercel/ncc": "^0.31.1",
|
"@vercel/ncc": "^0.36.0",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^8.30.0",
|
||||||
"eslint-plugin-github": "^2.0.0",
|
"eslint-plugin-github": "^4.6.0",
|
||||||
"eslint-plugin-jest": "^22.21.0",
|
"eslint-plugin-jest": "^27.1.7",
|
||||||
"jest": "^27.3.1",
|
"jest": "^29.3.1",
|
||||||
"jest-circus": "^27.3.1",
|
"jest-circus": "^29.3.1",
|
||||||
"js-yaml": "^3.13.1",
|
"js-yaml": "^4.1.0",
|
||||||
"prettier": "^1.19.1",
|
"msw": "^0.49.2",
|
||||||
"ts-jest": "^27.0.7",
|
"prettier": "^2.8.1",
|
||||||
"typescript": "^3.6.4"
|
"ts-jest": "^29.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
134
src/delete.ts
134
src/delete.ts
@@ -1,46 +1,104 @@
|
|||||||
|
/* eslint-disable i18n-text/no-en */
|
||||||
|
|
||||||
import {Input} from './input'
|
import {Input} from './input'
|
||||||
import {Observable, of, throwError} from 'rxjs'
|
import {EMPTY, Observable, of, throwError} from 'rxjs'
|
||||||
import {deletePackageVersions, getOldestVersions} from './version'
|
import {reduce, concatMap, map, expand, tap} from 'rxjs/operators'
|
||||||
import {concatMap, map} from 'rxjs/operators'
|
import {
|
||||||
|
deletePackageVersions,
|
||||||
|
getOldestVersions,
|
||||||
|
RestVersionInfo
|
||||||
|
} from './version'
|
||||||
|
|
||||||
export function getVersionIds(input: Input): Observable<string[]> {
|
export const RATE_LIMIT = 100
|
||||||
|
let totalCount = 0
|
||||||
|
|
||||||
|
export function getVersionIds(
|
||||||
|
owner: string,
|
||||||
|
packageName: string,
|
||||||
|
packageType: string,
|
||||||
|
numVersions: number,
|
||||||
|
page: number,
|
||||||
|
token: string
|
||||||
|
): Observable<RestVersionInfo[]> {
|
||||||
|
return getOldestVersions(
|
||||||
|
owner,
|
||||||
|
packageName,
|
||||||
|
packageType,
|
||||||
|
numVersions,
|
||||||
|
page,
|
||||||
|
token
|
||||||
|
).pipe(
|
||||||
|
expand(value =>
|
||||||
|
value.paginate
|
||||||
|
? getOldestVersions(
|
||||||
|
owner,
|
||||||
|
packageName,
|
||||||
|
packageType,
|
||||||
|
numVersions,
|
||||||
|
value.page + 1,
|
||||||
|
token
|
||||||
|
)
|
||||||
|
: EMPTY
|
||||||
|
),
|
||||||
|
tap(value => (totalCount = totalCount + value.totalCount)),
|
||||||
|
reduce((acc, value) => acc.concat(value.versions), [] as RestVersionInfo[])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function finalIds(input: Input): Observable<string[]> {
|
||||||
if (input.packageVersionIds.length > 0) {
|
if (input.packageVersionIds.length > 0) {
|
||||||
return of(input.packageVersionIds)
|
const toDelete = Math.min(input.packageVersionIds.length, RATE_LIMIT)
|
||||||
|
return of(input.packageVersionIds.slice(0, toDelete))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.hasOldestVersionQueryInfo()) {
|
if (input.hasOldestVersionQueryInfo()) {
|
||||||
return getOldestVersions(
|
return getVersionIds(
|
||||||
input.owner,
|
input.owner,
|
||||||
input.repo,
|
|
||||||
input.packageName,
|
input.packageName,
|
||||||
input.numOldVersionsToDelete + input.minVersionsToKeep,
|
input.packageType,
|
||||||
|
RATE_LIMIT,
|
||||||
|
1,
|
||||||
input.token
|
input.token
|
||||||
).pipe(
|
).pipe(
|
||||||
map(versionInfo => {
|
// This code block executes on all versions of a package starting from oldest
|
||||||
const numberVersionsToDelete =
|
map(value => {
|
||||||
versionInfo.length - input.minVersionsToKeep
|
// we need to delete oldest versions first
|
||||||
|
value.sort((a, b) => {
|
||||||
|
if (a.created_at === b.created_at) {
|
||||||
|
return a.id - b.id
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
/*
|
||||||
|
Here first filter out the versions that are to be ignored.
|
||||||
|
Then compute number of versions to delete (toDelete) based on the inputs.
|
||||||
|
*/
|
||||||
|
value = value.filter(info => !input.ignoreVersions.test(info.version))
|
||||||
|
|
||||||
if (input.minVersionsToKeep > 0) {
|
if (input.deleteUntaggedVersions === 'true') {
|
||||||
return numberVersionsToDelete <= 0
|
value = value.filter(info => !info.tagged)
|
||||||
? []
|
|
||||||
: versionInfo
|
|
||||||
.filter(info => !input.ignoreVersions.test(info.version))
|
|
||||||
.map(info => info.id)
|
|
||||||
.slice(0, -input.minVersionsToKeep)
|
|
||||||
} else {
|
|
||||||
return numberVersionsToDelete <= 0
|
|
||||||
? []
|
|
||||||
: versionInfo
|
|
||||||
.filter(info => !input.ignoreVersions.test(info.version))
|
|
||||||
.map(info => info.id)
|
|
||||||
.slice(0, numberVersionsToDelete)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let toDelete = 0
|
||||||
|
if (input.minVersionsToKeep < 0) {
|
||||||
|
toDelete = Math.min(
|
||||||
|
value.length,
|
||||||
|
Math.min(input.numOldVersionsToDelete, RATE_LIMIT)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
toDelete = Math.min(
|
||||||
|
value.length - input.minVersionsToKeep,
|
||||||
|
RATE_LIMIT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (toDelete < 0) return []
|
||||||
|
return value.map(info => info.id.toString()).slice(0, toDelete)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return throwError(
|
return throwError(
|
||||||
"Could not get packageVersionIds. Explicitly specify using the 'package-version-ids' input or provide the 'package-name' and 'num-old-versions-to-delete' inputs to dynamically retrieve oldest versions"
|
"Could not get packageVersionIds. Explicitly specify using the 'package-version-ids' input"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,14 +107,28 @@ export function deleteVersions(input: Input): Observable<boolean> {
|
|||||||
return throwError('No token found')
|
return throwError('No token found')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.numOldVersionsToDelete <= 0) {
|
if (!input.checkInput()) {
|
||||||
|
return throwError('Invalid input combination')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.numOldVersionsToDelete <= 0 && input.minVersionsToKeep < 0) {
|
||||||
console.log(
|
console.log(
|
||||||
'Number of old versions to delete input is 0 or less, no versions will be deleted'
|
'Number of old versions to delete input is 0 or less, no versions will be deleted'
|
||||||
)
|
)
|
||||||
return of(true)
|
return of(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return getVersionIds(input).pipe(
|
const result = finalIds(input)
|
||||||
concatMap(ids => deletePackageVersions(ids, input.token))
|
|
||||||
|
return result.pipe(
|
||||||
|
concatMap(ids =>
|
||||||
|
deletePackageVersions(
|
||||||
|
ids,
|
||||||
|
input.owner,
|
||||||
|
input.packageName,
|
||||||
|
input.packageType,
|
||||||
|
input.token
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
65
src/input.ts
65
src/input.ts
@@ -1,69 +1,100 @@
|
|||||||
export interface InputParams {
|
export interface InputParams {
|
||||||
packageVersionIds?: string[]
|
packageVersionIds?: string[]
|
||||||
owner?: string
|
owner?: string
|
||||||
repo?: string
|
|
||||||
packageName?: string
|
packageName?: string
|
||||||
|
packageType?: string
|
||||||
numOldVersionsToDelete?: number
|
numOldVersionsToDelete?: number
|
||||||
minVersionsToKeep?: number
|
minVersionsToKeep?: number
|
||||||
ignoreVersions?: RegExp
|
ignoreVersions?: RegExp
|
||||||
token?: string
|
token?: string
|
||||||
deletePreReleaseVersions?: string
|
deletePreReleaseVersions?: string
|
||||||
|
deleteUntaggedVersions?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultParams = {
|
const defaultParams = {
|
||||||
packageVersionIds: [],
|
packageVersionIds: [],
|
||||||
owner: '',
|
owner: '',
|
||||||
repo: '',
|
|
||||||
packageName: '',
|
packageName: '',
|
||||||
|
packageType: '',
|
||||||
numOldVersionsToDelete: 0,
|
numOldVersionsToDelete: 0,
|
||||||
minVersionsToKeep: 0,
|
minVersionsToKeep: 0,
|
||||||
ignoreVersions: new RegExp(''),
|
ignoreVersions: new RegExp(''),
|
||||||
deletePreReleaseVersions: '',
|
deletePreReleaseVersions: '',
|
||||||
token: ''
|
token: '',
|
||||||
|
deleteUntaggedVersions: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Input {
|
export class Input {
|
||||||
packageVersionIds: string[]
|
packageVersionIds: string[]
|
||||||
owner: string
|
owner: string
|
||||||
repo: string
|
|
||||||
packageName: string
|
packageName: string
|
||||||
|
packageType: string
|
||||||
numOldVersionsToDelete: number
|
numOldVersionsToDelete: number
|
||||||
minVersionsToKeep: number
|
minVersionsToKeep: number
|
||||||
ignoreVersions: RegExp
|
ignoreVersions: RegExp
|
||||||
deletePreReleaseVersions: string
|
deletePreReleaseVersions: string
|
||||||
token: string
|
token: string
|
||||||
|
numDeleted: number
|
||||||
|
deleteUntaggedVersions: string
|
||||||
|
|
||||||
constructor(params?: InputParams) {
|
constructor(params?: InputParams) {
|
||||||
const validatedParams: Required<InputParams> = {...defaultParams, ...params}
|
const validatedParams: Required<InputParams> = {...defaultParams, ...params}
|
||||||
|
|
||||||
this.packageVersionIds = validatedParams.packageVersionIds
|
this.packageVersionIds = validatedParams.packageVersionIds
|
||||||
this.owner = validatedParams.owner
|
this.owner = validatedParams.owner
|
||||||
this.repo = validatedParams.repo
|
|
||||||
this.packageName = validatedParams.packageName
|
this.packageName = validatedParams.packageName
|
||||||
|
this.packageType = validatedParams.packageType
|
||||||
this.numOldVersionsToDelete = validatedParams.numOldVersionsToDelete
|
this.numOldVersionsToDelete = validatedParams.numOldVersionsToDelete
|
||||||
this.minVersionsToKeep = validatedParams.minVersionsToKeep
|
this.minVersionsToKeep = validatedParams.minVersionsToKeep
|
||||||
this.ignoreVersions = validatedParams.ignoreVersions
|
this.ignoreVersions = validatedParams.ignoreVersions
|
||||||
this.deletePreReleaseVersions = validatedParams.deletePreReleaseVersions
|
this.deletePreReleaseVersions = validatedParams.deletePreReleaseVersions
|
||||||
this.token = validatedParams.token
|
this.token = validatedParams.token
|
||||||
|
this.numDeleted = 0
|
||||||
if (this.minVersionsToKeep > 0) {
|
this.deleteUntaggedVersions = validatedParams.deleteUntaggedVersions
|
||||||
this.numOldVersionsToDelete = 100 - this.minVersionsToKeep
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.deletePreReleaseVersions == 'true') {
|
|
||||||
this.numOldVersionsToDelete = 100 - this.minVersionsToKeep
|
|
||||||
this.ignoreVersions = new RegExp('^(0|[1-9]\\d*)((\\.(0|[1-9]\\d*))*)$')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hasOldestVersionQueryInfo(): boolean {
|
hasOldestVersionQueryInfo(): boolean {
|
||||||
return !!(
|
return !!(
|
||||||
this.owner &&
|
this.owner &&
|
||||||
this.repo &&
|
|
||||||
this.packageName &&
|
this.packageName &&
|
||||||
this.numOldVersionsToDelete > 0 &&
|
this.numOldVersionsToDelete >= 0 &&
|
||||||
this.minVersionsToKeep >= 0 &&
|
|
||||||
this.token
|
this.token
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkInput(): boolean {
|
||||||
|
if (this.packageType.toLowerCase() !== 'container') {
|
||||||
|
this.deleteUntaggedVersions = 'false'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.numOldVersionsToDelete > 1 &&
|
||||||
|
(this.minVersionsToKeep >= 0 ||
|
||||||
|
this.deletePreReleaseVersions === 'true' ||
|
||||||
|
this.deleteUntaggedVersions === 'true')
|
||||||
|
) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.packageType === '' || this.packageName === '') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.deletePreReleaseVersions === 'true') {
|
||||||
|
this.minVersionsToKeep =
|
||||||
|
this.minVersionsToKeep > 0 ? this.minVersionsToKeep : 0
|
||||||
|
this.ignoreVersions = new RegExp('^(0|[1-9]\\d*)((\\.(0|[1-9]\\d*))*)$')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.deleteUntaggedVersions === 'true') {
|
||||||
|
this.minVersionsToKeep =
|
||||||
|
this.minVersionsToKeep > 0 ? this.minVersionsToKeep : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.minVersionsToKeep >= 0) {
|
||||||
|
this.numOldVersionsToDelete = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/main.ts
12
src/main.ts
@@ -11,15 +11,18 @@ function getActionInput(): Input {
|
|||||||
? getInput('package-version-ids').split(',')
|
? getInput('package-version-ids').split(',')
|
||||||
: [],
|
: [],
|
||||||
owner: getInput('owner') ? getInput('owner') : context.repo.owner,
|
owner: getInput('owner') ? getInput('owner') : context.repo.owner,
|
||||||
repo: getInput('repo') ? getInput('repo') : context.repo.repo,
|
|
||||||
packageName: getInput('package-name'),
|
packageName: getInput('package-name'),
|
||||||
|
packageType: getInput('package-type'),
|
||||||
numOldVersionsToDelete: Number(getInput('num-old-versions-to-delete')),
|
numOldVersionsToDelete: Number(getInput('num-old-versions-to-delete')),
|
||||||
minVersionsToKeep: Number(getInput('min-versions-to-keep')),
|
minVersionsToKeep: Number(getInput('min-versions-to-keep')),
|
||||||
ignoreVersions: RegExp(getInput('ignore-versions')),
|
ignoreVersions: RegExp(getInput('ignore-versions')),
|
||||||
deletePreReleaseVersions: getInput(
|
deletePreReleaseVersions: getInput(
|
||||||
'delete-only-pre-release-versions'
|
'delete-only-pre-release-versions'
|
||||||
).toLowerCase(),
|
).toLowerCase(),
|
||||||
token: getInput('token')
|
token: getInput('token'),
|
||||||
|
deleteUntaggedVersions: getInput(
|
||||||
|
'delete-only-untagged-versions'
|
||||||
|
).toLowerCase()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +32,10 @@ function run(): Observable<boolean> {
|
|||||||
catchError(err => throwError(err))
|
catchError(err => throwError(err))
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return throwError(error.message)
|
if (error instanceof Error) {
|
||||||
|
return throwError(error.message)
|
||||||
|
}
|
||||||
|
return throwError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,65 +1,67 @@
|
|||||||
import {from, Observable, merge, throwError, of} from 'rxjs'
|
import {from, Observable, merge, throwError, of} from 'rxjs'
|
||||||
import {catchError, map, tap} from 'rxjs/operators'
|
import {catchError, map, tap} from 'rxjs/operators'
|
||||||
import {GraphQlQueryResponse} from '@octokit/graphql/dist-types/types'
|
import {Octokit} from '@octokit/rest'
|
||||||
import {graphql} from './graphql'
|
import {RestEndpointMethodTypes} from '@octokit/plugin-rest-endpoint-methods/dist-types/generated/parameters-and-response-types'
|
||||||
|
|
||||||
export interface DeletePackageVersionMutationResponse {
|
let deleted = 0
|
||||||
deletePackageVersion: {
|
type PackageType =
|
||||||
success: boolean
|
RestEndpointMethodTypes['packages']['getAllPackageVersionsForPackageOwnedByUser']['parameters']['package_type']
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const mutation = `
|
|
||||||
mutation deletePackageVersion($packageVersionId: String!) {
|
|
||||||
deletePackageVersion(input: {packageVersionId: $packageVersionId}) {
|
|
||||||
success
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
|
|
||||||
export function deletePackageVersion(
|
export function deletePackageVersion(
|
||||||
packageVersionId: string,
|
packageVersionId: string,
|
||||||
|
owner: string,
|
||||||
|
packageName: string,
|
||||||
|
packageType: string,
|
||||||
token: string
|
token: string
|
||||||
): Observable<boolean> {
|
): Observable<boolean> {
|
||||||
|
const octokit = new Octokit({
|
||||||
|
auth: token,
|
||||||
|
baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com'
|
||||||
|
})
|
||||||
|
const package_version_id = +packageVersionId
|
||||||
|
const package_type: PackageType = packageType as PackageType
|
||||||
|
deleted += 1
|
||||||
|
|
||||||
return from(
|
return from(
|
||||||
graphql(token, mutation, {
|
octokit.rest.packages.deletePackageVersionForUser({
|
||||||
packageVersionId,
|
package_type,
|
||||||
headers: {
|
package_name: packageName,
|
||||||
Accept: 'application/vnd.github.package-deletes-preview+json'
|
username: owner,
|
||||||
}
|
package_version_id
|
||||||
}) as Promise<DeletePackageVersionMutationResponse>
|
})
|
||||||
).pipe(
|
).pipe(
|
||||||
catchError((err: GraphQlQueryResponse) => {
|
catchError(err => {
|
||||||
const msg = 'delete version mutation failed.'
|
const msg = 'delete version API failed.'
|
||||||
return throwError(
|
return throwError(
|
||||||
err.errors && err.errors.length > 0
|
err.errors && err.errors.length > 0
|
||||||
? `${msg} ${err.errors[0].message}`
|
? `${msg} ${err.errors[0].message}`
|
||||||
: `${msg} verify input parameters are correct`
|
: `${msg} ${err.message} \n${deleted - 1} versions deleted till now.`
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
map(response => response.deletePackageVersion.success)
|
map(response => response.status === 204)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deletePackageVersions(
|
export function deletePackageVersions(
|
||||||
packageVersionIds: string[],
|
packageVersionIds: string[],
|
||||||
|
owner: string,
|
||||||
|
packageName: string,
|
||||||
|
packageType: string,
|
||||||
token: string
|
token: string
|
||||||
): Observable<boolean> {
|
): Observable<boolean> {
|
||||||
if (packageVersionIds.length === 0) {
|
if (packageVersionIds.length === 0) {
|
||||||
console.log('no package version ids found, no versions will be deleted')
|
|
||||||
return of(true)
|
return of(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const deletes = packageVersionIds.map(id =>
|
const deletes = packageVersionIds.map(id =>
|
||||||
deletePackageVersion(id, token).pipe(
|
deletePackageVersion(id, owner, packageName, packageType, token).pipe(
|
||||||
tap(result => {
|
tap(result => {
|
||||||
if (result) {
|
if (!result) {
|
||||||
console.log(`version with id: ${id}, deleted`)
|
|
||||||
} else {
|
|
||||||
console.log(`version with id: ${id}, not deleted`)
|
console.log(`version with id: ${id}, not deleted`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
console.log(`Total versions deleted till now: ${deleted}`)
|
||||||
return merge(...deletes)
|
return merge(...deletes)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,111 +1,83 @@
|
|||||||
import {GraphQlQueryResponse} from '@octokit/graphql/dist-types/types'
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
import {Observable, from, throwError} from 'rxjs'
|
import {from, Observable, merge, throwError, of} from 'rxjs'
|
||||||
import {catchError, map} from 'rxjs/operators'
|
import {catchError, map} from 'rxjs/operators'
|
||||||
import {graphql} from './graphql'
|
import {Octokit} from '@octokit/rest'
|
||||||
|
import {RestEndpointMethodTypes} from '@octokit/plugin-rest-endpoint-methods/dist-types/generated/parameters-and-response-types'
|
||||||
|
|
||||||
export interface VersionInfo {
|
export interface RestVersionInfo {
|
||||||
id: string
|
id: number
|
||||||
version: string
|
version: string
|
||||||
|
created_at: string
|
||||||
|
tagged: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GetVersionsQueryResponse {
|
export interface RestQueryInfo {
|
||||||
repository: {
|
versions: RestVersionInfo[]
|
||||||
packages: {
|
page: number
|
||||||
edges: {
|
paginate: boolean
|
||||||
node: {
|
totalCount: number
|
||||||
name: string
|
|
||||||
versions: {
|
|
||||||
edges: {node: VersionInfo}[]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}[]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = `
|
type PackageType =
|
||||||
query getVersions($owner: String!, $repo: String!, $package: String!, $last: Int!) {
|
RestEndpointMethodTypes['packages']['getAllPackageVersionsForPackageOwnedByUser']['parameters']['package_type']
|
||||||
repository(owner: $owner, name: $repo) {
|
type GetVersionsResponse =
|
||||||
packages(first: 1, names: [$package]) {
|
RestEndpointMethodTypes['packages']['getAllPackageVersionsForPackageOwnedByUser']['response']['data']
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
name
|
|
||||||
versions(last: $last) {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
id
|
|
||||||
version
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
|
|
||||||
export function queryForOldestVersions(
|
|
||||||
owner: string,
|
|
||||||
repo: string,
|
|
||||||
packageName: string,
|
|
||||||
numVersions: number,
|
|
||||||
token: string
|
|
||||||
): Observable<GetVersionsQueryResponse> {
|
|
||||||
return from(
|
|
||||||
graphql(token, query, {
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
package: packageName,
|
|
||||||
last: numVersions,
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/vnd.github.packages-preview+json'
|
|
||||||
}
|
|
||||||
}) as Promise<GetVersionsQueryResponse>
|
|
||||||
).pipe(
|
|
||||||
catchError((err: GraphQlQueryResponse) => {
|
|
||||||
const msg = 'query for oldest version failed.'
|
|
||||||
return throwError(
|
|
||||||
err.errors && err.errors.length > 0
|
|
||||||
? `${msg} ${err.errors[0].message}`
|
|
||||||
: `${msg} verify input parameters are correct`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getOldestVersions(
|
export function getOldestVersions(
|
||||||
owner: string,
|
owner: string,
|
||||||
repo: string,
|
|
||||||
packageName: string,
|
packageName: string,
|
||||||
|
packageType: string,
|
||||||
numVersions: number,
|
numVersions: number,
|
||||||
|
page: number,
|
||||||
token: string
|
token: string
|
||||||
): Observable<VersionInfo[]> {
|
): Observable<RestQueryInfo> {
|
||||||
return queryForOldestVersions(
|
const octokit = new Octokit({
|
||||||
owner,
|
auth: token,
|
||||||
repo,
|
baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com'
|
||||||
packageName,
|
})
|
||||||
numVersions,
|
const package_type: PackageType = packageType as PackageType
|
||||||
token
|
|
||||||
|
return from(
|
||||||
|
octokit.rest.packages.getAllPackageVersionsForPackageOwnedByUser({
|
||||||
|
package_type,
|
||||||
|
package_name: packageName,
|
||||||
|
username: owner,
|
||||||
|
per_page: numVersions,
|
||||||
|
page
|
||||||
|
})
|
||||||
).pipe(
|
).pipe(
|
||||||
map(result => {
|
catchError(err => {
|
||||||
if (result.repository.packages.edges.length < 1) {
|
const msg = 'get versions API failed.'
|
||||||
console.log(
|
return throwError(
|
||||||
`package: ${packageName} not found for owner: ${owner} in repo: ${repo}`
|
err.errors && err.errors.length > 0
|
||||||
)
|
? `${msg} ${err.errors[0].message}`
|
||||||
return []
|
: `${msg} ${err.message}`
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
map(response => {
|
||||||
|
const resp = {
|
||||||
|
versions: response.data.map((version: GetVersionsResponse[0]) => {
|
||||||
|
let tagged = false
|
||||||
|
if (
|
||||||
|
package_type === 'container' &&
|
||||||
|
version.metadata &&
|
||||||
|
version.metadata.container
|
||||||
|
) {
|
||||||
|
tagged = version.metadata.container.tags.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: version.id,
|
||||||
|
version: version.name,
|
||||||
|
created_at: version.created_at,
|
||||||
|
tagged
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
page,
|
||||||
|
paginate: response.data.length === numVersions,
|
||||||
|
totalCount: response.data.length
|
||||||
}
|
}
|
||||||
|
return resp
|
||||||
const versions = result.repository.packages.edges[0].node.versions.edges
|
|
||||||
|
|
||||||
if (versions.length !== numVersions) {
|
|
||||||
console.log(
|
|
||||||
`number of versions requested was: ${numVersions}, but found: ${versions.length}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return versions
|
|
||||||
.map(value => ({id: value.node.id, version: value.node.version}))
|
|
||||||
.reverse()
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
import {GitHub} from '@actions/github'
|
|
||||||
import {GraphQlQueryResponseData} from '@octokit/graphql/dist-types/types'
|
|
||||||
import {RequestParameters} from '@octokit/types/dist-types/RequestParameters'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a GraphQL query request based on endpoint options
|
|
||||||
*
|
|
||||||
* @param {string} token Auth token
|
|
||||||
* @param {string} query GraphQL query. Example: `'query { viewer { login } }'`.
|
|
||||||
* @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
|
|
||||||
*/
|
|
||||||
export async function graphql(
|
|
||||||
token: string,
|
|
||||||
query: string,
|
|
||||||
parameters: RequestParameters
|
|
||||||
): Promise<GraphQlQueryResponseData> {
|
|
||||||
const github = new GitHub(token)
|
|
||||||
return await github.graphql(query, parameters)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user