Releases/v1 (#1)
* delete package versions action v1 * updated action for build and smoke test * test and error message update * test fix * ci testing * ci testing * ci testing * ci testing * ci test * ci testing * ci test name * docs * docs * docs * test * test * test * docs * usage doc * doc * docs * format test * doc update * doc test * formatting check * scenario update * usage update * format * test * test * test * test * test * table test * test * format update * links * test * test * test * test * test * docs update * test * formatting * fix broken links * doc update * test * table test * test * test * test * test * test * test * test * test * test * test * doc test * test * test * test * test * test * test * test t * test * test * test * test * test * test * docs * doc update
This commit is contained in:
41
src/delete.ts
Normal file
41
src/delete.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import {Input} from './input'
|
||||
import {Observable, of, throwError} from 'rxjs'
|
||||
import {deletePackageVersions, getOldestVersions} from './version'
|
||||
import {concatMap, map} from 'rxjs/operators'
|
||||
|
||||
export function getVersionIds(input: Input): Observable<string[]> {
|
||||
if (input.packageVersionIds.length > 0) {
|
||||
return of(input.packageVersionIds)
|
||||
}
|
||||
|
||||
if (input.hasOldestVersionQueryInfo()) {
|
||||
return getOldestVersions(
|
||||
input.owner,
|
||||
input.repo,
|
||||
input.packageName,
|
||||
input.numOldVersionsToDelete,
|
||||
input.token
|
||||
).pipe(map(versionInfo => versionInfo.map(info => info.id)))
|
||||
}
|
||||
|
||||
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"
|
||||
)
|
||||
}
|
||||
|
||||
export function deleteVersions(input: Input): Observable<boolean> {
|
||||
if (!input.token) {
|
||||
return throwError('No token found')
|
||||
}
|
||||
|
||||
if (input.numOldVersionsToDelete <= 0) {
|
||||
console.log(
|
||||
'Number of old versions to delete input is 0 or less, no versions will be deleted'
|
||||
)
|
||||
return of(true)
|
||||
}
|
||||
|
||||
return getVersionIds(input).pipe(
|
||||
concatMap(ids => deletePackageVersions(ids, input.token))
|
||||
)
|
||||
}
|
||||
47
src/input.ts
Normal file
47
src/input.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
export interface InputParams {
|
||||
packageVersionIds?: string[]
|
||||
owner?: string
|
||||
repo?: string
|
||||
packageName?: string
|
||||
numOldVersionsToDelete?: number
|
||||
token?: string
|
||||
}
|
||||
|
||||
const defaultParams = {
|
||||
packageVersionIds: [],
|
||||
owner: '',
|
||||
repo: '',
|
||||
packageName: '',
|
||||
numOldVersionsToDelete: 0,
|
||||
token: ''
|
||||
}
|
||||
|
||||
export class Input {
|
||||
packageVersionIds: string[]
|
||||
owner: string
|
||||
repo: string
|
||||
packageName: string
|
||||
numOldVersionsToDelete: number
|
||||
token: string
|
||||
|
||||
constructor(params?: InputParams) {
|
||||
const validatedParams: Required<InputParams> = {...defaultParams, ...params}
|
||||
|
||||
this.packageVersionIds = validatedParams.packageVersionIds
|
||||
this.owner = validatedParams.owner
|
||||
this.repo = validatedParams.repo
|
||||
this.packageName = validatedParams.packageName
|
||||
this.numOldVersionsToDelete = validatedParams.numOldVersionsToDelete
|
||||
this.token = validatedParams.token
|
||||
}
|
||||
|
||||
hasOldestVersionQueryInfo(): boolean {
|
||||
return !!(
|
||||
this.owner &&
|
||||
this.repo &&
|
||||
this.packageName &&
|
||||
this.numOldVersionsToDelete > 0 &&
|
||||
this.token
|
||||
)
|
||||
}
|
||||
}
|
||||
42
src/main.ts
42
src/main.ts
@@ -1,19 +1,35 @@
|
||||
import * as core from '@actions/core'
|
||||
import {wait} from './wait'
|
||||
import {getInput, setFailed} from '@actions/core'
|
||||
import {context} from '@actions/github'
|
||||
import {Input} from './input'
|
||||
import {Observable, throwError} from 'rxjs'
|
||||
import {deleteVersions} from './delete'
|
||||
import {catchError} from 'rxjs/operators'
|
||||
|
||||
async function run(): Promise<void> {
|
||||
function getActionInput(): Input {
|
||||
return new Input({
|
||||
packageVersionIds: getInput('package-version-ids')
|
||||
? getInput('package-version-ids').split(',')
|
||||
: [],
|
||||
owner: getInput('owner') ? getInput('owner') : context.repo.owner,
|
||||
repo: getInput('repo') ? getInput('repo') : context.repo.repo,
|
||||
packageName: getInput('package-name'),
|
||||
numOldVersionsToDelete: Number(getInput('num-old-versions-to-delete')),
|
||||
token: getInput('token')
|
||||
})
|
||||
}
|
||||
|
||||
function run(): Observable<boolean> {
|
||||
try {
|
||||
const ms: string = core.getInput('milliseconds')
|
||||
core.debug(`Waiting ${ms} milliseconds ...`)
|
||||
|
||||
core.debug(new Date().toTimeString())
|
||||
await wait(parseInt(ms, 10))
|
||||
core.debug(new Date().toTimeString())
|
||||
|
||||
core.setOutput('time', new Date().toTimeString())
|
||||
return deleteVersions(getActionInput()).pipe(
|
||||
catchError(err => throwError(err))
|
||||
)
|
||||
} catch (error) {
|
||||
core.setFailed(error.message)
|
||||
return throwError(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
run()
|
||||
run().subscribe({
|
||||
error: err => {
|
||||
setFailed(err)
|
||||
}
|
||||
})
|
||||
|
||||
66
src/version/delete-version.ts
Normal file
66
src/version/delete-version.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import {from, Observable, merge, throwError, of} from 'rxjs'
|
||||
import {graphql} from '@octokit/graphql'
|
||||
import {catchError, map, tap} from 'rxjs/operators'
|
||||
import {GraphQlQueryResponse} from '@octokit/graphql/dist-types/types'
|
||||
|
||||
export interface DeletePackageVersionMutationResponse {
|
||||
deletePackageVersion: {
|
||||
success: boolean
|
||||
}
|
||||
}
|
||||
|
||||
const mutation = `
|
||||
mutation deletePackageVersion($packageVersionId: String!) {
|
||||
deletePackageVersion(input: {packageVersionId: $packageVersionId}) {
|
||||
success
|
||||
}
|
||||
}`
|
||||
|
||||
export function deletePackageVersion(
|
||||
packageVersionId: string,
|
||||
token: string
|
||||
): Observable<boolean> {
|
||||
return from(
|
||||
graphql(mutation, {
|
||||
packageVersionId,
|
||||
headers: {
|
||||
authorization: `token ${token}`,
|
||||
Accept: 'application/vnd.github.package-deletes-preview+json'
|
||||
}
|
||||
}) as Promise<DeletePackageVersionMutationResponse>
|
||||
).pipe(
|
||||
catchError((err: GraphQlQueryResponse) => {
|
||||
const msg = 'delete version mutation failed.'
|
||||
return throwError(
|
||||
err.errors && err.errors.length > 0
|
||||
? `${msg} ${err.errors[0].message}`
|
||||
: `${msg} verify input parameters are correct`
|
||||
)
|
||||
}),
|
||||
map(response => response.deletePackageVersion.success)
|
||||
)
|
||||
}
|
||||
|
||||
export function deletePackageVersions(
|
||||
packageVersionIds: string[],
|
||||
token: string
|
||||
): Observable<boolean> {
|
||||
if (packageVersionIds.length === 0) {
|
||||
console.log('no package version ids found, no versions will be deleted')
|
||||
return of(true)
|
||||
}
|
||||
|
||||
const deletes = packageVersionIds.map(id =>
|
||||
deletePackageVersion(id, token).pipe(
|
||||
tap(result => {
|
||||
if (result) {
|
||||
console.log(`version with id: ${id}, deleted`)
|
||||
} else {
|
||||
console.log(`version with id: ${id}, not deleted`)
|
||||
}
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
return merge(...deletes)
|
||||
}
|
||||
111
src/version/get-versions.ts
Normal file
111
src/version/get-versions.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import {graphql} from '@octokit/graphql'
|
||||
import {GraphQlQueryResponse} from '@octokit/graphql/dist-types/types'
|
||||
import {Observable, from, throwError} from 'rxjs'
|
||||
import {catchError, map} from 'rxjs/operators'
|
||||
|
||||
export interface VersionInfo {
|
||||
id: string
|
||||
version: string
|
||||
}
|
||||
|
||||
export interface GetVersionsQueryResponse {
|
||||
repository: {
|
||||
packages: {
|
||||
edges: {
|
||||
node: {
|
||||
name: string
|
||||
versions: {
|
||||
edges: {node: VersionInfo}[]
|
||||
}
|
||||
}
|
||||
}[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const query = `
|
||||
query getVersions($owner: String!, $repo: String!, $package: String!, $last: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
packages(first: 1, names: [$package]) {
|
||||
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(query, {
|
||||
owner,
|
||||
repo,
|
||||
package: packageName,
|
||||
last: numVersions,
|
||||
headers: {
|
||||
authorization: `token ${token}`,
|
||||
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(
|
||||
owner: string,
|
||||
repo: string,
|
||||
packageName: string,
|
||||
numVersions: number,
|
||||
token: string
|
||||
): Observable<VersionInfo[]> {
|
||||
return queryForOldestVersions(
|
||||
owner,
|
||||
repo,
|
||||
packageName,
|
||||
numVersions,
|
||||
token
|
||||
).pipe(
|
||||
map(result => {
|
||||
if (result.repository.packages.edges.length < 1) {
|
||||
throwError(
|
||||
`package: ${packageName} not found for owner: ${owner} in repo: ${repo}`
|
||||
)
|
||||
}
|
||||
|
||||
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()
|
||||
})
|
||||
)
|
||||
}
|
||||
2
src/version/index.ts
Normal file
2
src/version/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './get-versions'
|
||||
export * from './delete-version'
|
||||
@@ -1,9 +0,0 @@
|
||||
export async function wait(milliseconds: number): Promise<string> {
|
||||
return new Promise(resolve => {
|
||||
if (isNaN(milliseconds)) {
|
||||
throw new Error('milliseconds not a number')
|
||||
}
|
||||
|
||||
setTimeout(() => resolve('done!'), milliseconds)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user