mirror of
https://github.com/MillironX/setup-nextflow.git
synced 2024-11-23 10:09:54 +00:00
Compare commits
33 commits
bb811ccf98
...
6d07f25101
Author | SHA1 | Date | |
---|---|---|---|
6d07f25101 | |||
ad89639887 | |||
65a3486a82 | |||
a0546498bf | |||
3b23b7abfe | |||
d3023422c1 | |||
eaeab23c1a | |||
5d1d40a4ea | |||
20ed9d58ea | |||
e8d313e9d2 | |||
34cd96c6c5 | |||
29edf6bed3 | |||
1927f1a07e | |||
21ad9d9cb6 | |||
525dd341cb | |||
31898fbe2b | |||
2145dbec41 | |||
243e2d8f57 | |||
76b5d90248 | |||
34b2731a55 | |||
e259f2a032 | |||
d4db5065bf | |||
f65f3889f1 | |||
92d5fbf3ef | |||
3fdf4e64ae | |||
f4e0bf4b97 | |||
34c114ad83 | |||
78ff7697d2 | |||
6174369e79 | |||
199dd22747 | |||
a4976909b6 | |||
74ebaacc41 | |||
222380fece |
23 changed files with 1109 additions and 487 deletions
3
.actrc
Normal file
3
.actrc
Normal file
|
@ -0,0 +1,3 @@
|
|||
-P ubuntu-latest=catthehacker/ubuntu:act-latest
|
||||
-s GITHUB_TOKEN
|
||||
--container-architecture linux/amd64
|
14
.github/workflows/example.yml
vendored
14
.github/workflows/example.yml
vendored
|
@ -10,7 +10,7 @@ on:
|
|||
types: [published]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
example-usage:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
|
@ -37,13 +37,18 @@ jobs:
|
|||
- run: npm ci
|
||||
- run: npm run build
|
||||
- run: npm run package
|
||||
- uses: actions/setup-java@v2
|
||||
if: ${{ env.ACT }}
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: zulu
|
||||
- uses: ./
|
||||
with:
|
||||
version: ${{ matrix.nextflow_version }}
|
||||
all: ${{ matrix.all_distribution }}
|
||||
- run: nextflow -v
|
||||
|
||||
test-14:
|
||||
example-maximized-build-space:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: easimon/maximize-build-space@v7
|
||||
|
@ -55,5 +60,10 @@ jobs:
|
|||
- run: npm ci
|
||||
- run: npm run build
|
||||
- run: npm run package
|
||||
- uses: actions/setup-java@v2
|
||||
if: ${{ env.ACT}}
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: zulu
|
||||
- uses: ./
|
||||
- run: nextflow -v
|
||||
|
|
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -89,7 +89,9 @@ out
|
|||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
# TODO: Remove the dist folder again after merging
|
||||
# This folder is only committed right now to allow for remote testing
|
||||
#dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
|
@ -131,4 +133,8 @@ dist
|
|||
|
||||
# Ignore built ts files
|
||||
__tests__/runner/*
|
||||
lib/**/*
|
||||
lib/**/*
|
||||
|
||||
# Testing garbage
|
||||
.tmp
|
||||
nxf-v*
|
||||
|
|
1
.husky/.gitignore
vendored
Normal file
1
.husky/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
_
|
2
.husky/pre-commit
Normal file
2
.husky/pre-commit
Normal file
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env sh
|
||||
npx lint-staged
|
24
.vscode/launch.json
vendored
Normal file
24
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch Action",
|
||||
"program": "${workspaceFolder}/src/main.ts",
|
||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||
"outFiles": ["${workspaceFolder}/lib/**/*.js"],
|
||||
"env": {
|
||||
"INPUT_ALL": "false",
|
||||
"INPUT_VERSION": "latest",
|
||||
"INPUT_TOKEN": "${env:GITHUB_TOKEN}",
|
||||
"INPUT_COOLDOWN": "60",
|
||||
"INPUT_MAX_RETRIES": "3",
|
||||
"RUNNER_TEMP": "${workspaceFolder}/.tmp"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- CI workflow steps for better compatibility with <https://github.com/nektos/act>
|
||||
- Visual Studio Code debugging configuration
|
||||
- Husky pre-commit hooks for linting and formatting
|
||||
|
||||
### Changed
|
||||
|
||||
- GitHub Octokit API switched to nf-core custom API
|
||||
|
||||
## [1.5.1] - 2024-01-30
|
||||
|
||||
### Changed
|
||||
|
|
12
action.yml
12
action.yml
|
@ -10,18 +10,6 @@ inputs:
|
|||
description: "Whether to install every Nextflow release via the '-all' distribution."
|
||||
required: false
|
||||
default: false
|
||||
token:
|
||||
description: "GitHub token to access the GitHub Releases API. The default token should be sufficient for all use cases."
|
||||
required: false
|
||||
default: ${{ github.token }}
|
||||
cooldown:
|
||||
description: "Time (in seconds) to wait before querying the GitHub Releases API in the case of hitting a rate limit."
|
||||
required: false
|
||||
default: "60"
|
||||
max-retries:
|
||||
description: "The number of times that to try querying the GitHub Releases API in case of a rate-limited failure."
|
||||
required: false
|
||||
default: "3"
|
||||
runs:
|
||||
using: "node16"
|
||||
main: "dist/index.js"
|
||||
|
|
BIN
dist/LICENSE
generated
vendored
Normal file
BIN
dist/LICENSE
generated
vendored
Normal file
Binary file not shown.
BIN
dist/index.js
generated
vendored
Normal file
BIN
dist/index.js
generated
vendored
Normal file
Binary file not shown.
BIN
dist/index.js.map
generated
vendored
Normal file
BIN
dist/index.js.map
generated
vendored
Normal file
Binary file not shown.
BIN
dist/sourcemap-register.js
generated
vendored
Normal file
BIN
dist/sourcemap-register.js
generated
vendored
Normal file
Binary file not shown.
943
package-lock.json
generated
943
package-lock.json
generated
File diff suppressed because it is too large
Load diff
13
package.json
13
package.json
|
@ -11,7 +11,8 @@
|
|||
"lint:fix": "eslint --fix {src,test}/**/*.ts",
|
||||
"package": "ncc build --source-map --license LICENSE",
|
||||
"test": "c8 --reporter=lcov ava",
|
||||
"all": "npm run build && npm run format && npm run lint && npm run package && npm test"
|
||||
"all": "npm run build && npm run format && npm run lint && npm run package && npm test",
|
||||
"prepare": "husky && husky install"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -27,6 +28,9 @@
|
|||
"extensions": [
|
||||
"ts"
|
||||
],
|
||||
"environmentVariables": {
|
||||
"RUNNER_TEMP": "./.tmp"
|
||||
},
|
||||
"rewritePaths": {
|
||||
"src/": "lib/"
|
||||
},
|
||||
|
@ -50,7 +54,6 @@
|
|||
"@actions/exec": "^1.1.1",
|
||||
"@actions/github": "^6.0.0",
|
||||
"@actions/tool-cache": "^2.0.1",
|
||||
"@octokit/plugin-throttling": "^8.1.3",
|
||||
"@types/node": "^17.0.44",
|
||||
"async-retry": "^1.3.3",
|
||||
"semver": "^7.3.7"
|
||||
|
@ -71,8 +74,14 @@
|
|||
"eslint-plugin-github": "^4.4.1",
|
||||
"eslint-plugin-jest": "^27.1.5",
|
||||
"eslint-plugin-simple-import-sort": "^8.0.0",
|
||||
"husky": "^9.0.10",
|
||||
"lint-staged": "^15.2.1",
|
||||
"prettier": "^2.7.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.7.3"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,ts}": "eslint --cache --fix",
|
||||
"*.{ts,js,yml,md,json}": "prettier --write"
|
||||
}
|
||||
}
|
||||
|
|
108
src/functions.ts
108
src/functions.ts
|
@ -6,115 +6,15 @@ import semver from "semver"
|
|||
|
||||
import { NextflowRelease } from "./nextflow-release"
|
||||
|
||||
async function get_latest_everything_nextflow_release(
|
||||
releases: AsyncGenerator<NextflowRelease>
|
||||
): Promise<NextflowRelease> {
|
||||
// Need to make sure we aren't in the edge case where a patch release is
|
||||
// more recent chronologically than the edge release
|
||||
let latest_release = {} as NextflowRelease
|
||||
|
||||
for await (const release of releases) {
|
||||
// First iteration:
|
||||
if (Object.keys(latest_release).length === 0) {
|
||||
// If the most recent release is an edge release, then we have nothing to
|
||||
// worry about, return it.
|
||||
if (release.isEdge) {
|
||||
return release
|
||||
}
|
||||
// Ok, so the most recent release is a stable release. We need to keep
|
||||
// tabs on it
|
||||
latest_release = release
|
||||
continue
|
||||
}
|
||||
|
||||
// A larger version number that is older than the "latest" release
|
||||
// indicates that we've hit an edge release that is more up-to-date
|
||||
// than a patch release. Return it.
|
||||
if (semver.gt(release.versionNumber, latest_release.versionNumber, true)) {
|
||||
return release
|
||||
}
|
||||
|
||||
// A smaller version number that is also an edge release indicates that the
|
||||
// chronologically most recent release is also the most up-to-date
|
||||
if (
|
||||
release.isEdge &&
|
||||
semver.lt(release.versionNumber, latest_release.versionNumber, true)
|
||||
) {
|
||||
return latest_release
|
||||
}
|
||||
|
||||
// Once we've hit the major.minor.0 of the version that is the most recent
|
||||
// patch, we know that we would have traversed any edge releases along the
|
||||
// way, so check to see if we've hit that point yet.
|
||||
const latest_release_major = semver.major(
|
||||
latest_release.versionNumber,
|
||||
true
|
||||
)
|
||||
const latest_release_minor = semver.minor(
|
||||
latest_release.versionNumber,
|
||||
true
|
||||
)
|
||||
const latest_release_minver = `${latest_release_major}.${latest_release_minor}.0`
|
||||
if (semver.eq(release.versionNumber, latest_release_minver, true)) {
|
||||
return latest_release
|
||||
}
|
||||
}
|
||||
|
||||
// We should never get here, but just in case
|
||||
return {} as NextflowRelease
|
||||
}
|
||||
|
||||
async function get_latest_edge_nextflow_release(
|
||||
releases: AsyncGenerator<NextflowRelease>
|
||||
): Promise<NextflowRelease> {
|
||||
// Because we don't have to worry about crossing between edge and stable
|
||||
// releases, we can just return the first edge release we come across
|
||||
for await (const release of releases) {
|
||||
if (release.isEdge) {
|
||||
return release
|
||||
}
|
||||
}
|
||||
|
||||
// We should never get here, but just in case
|
||||
return {} as NextflowRelease
|
||||
}
|
||||
|
||||
async function get_latest_stable_nextflow_release(
|
||||
releases: AsyncGenerator<NextflowRelease>
|
||||
): Promise<NextflowRelease> {
|
||||
// Because we don't have to worry about crossing between edge and stable
|
||||
// releases, we can just return the first stable release we come across
|
||||
for await (const release of releases) {
|
||||
if (!release.isEdge) {
|
||||
return release
|
||||
}
|
||||
}
|
||||
|
||||
// We should never get here, but just in case
|
||||
return {} as NextflowRelease
|
||||
}
|
||||
|
||||
export async function get_nextflow_release(
|
||||
version: string,
|
||||
releases: AsyncGenerator<NextflowRelease>
|
||||
releases: NextflowRelease[] | AsyncGenerator<NextflowRelease>
|
||||
): Promise<NextflowRelease> {
|
||||
// First, check to see if we are using a "latest-*" version system, and return
|
||||
// early
|
||||
if (version === "latest-everything") {
|
||||
return await get_latest_everything_nextflow_release(releases)
|
||||
}
|
||||
if (version === "latest-edge") {
|
||||
return await get_latest_edge_nextflow_release(releases)
|
||||
}
|
||||
if (version === "latest" || version === "latest-stable") {
|
||||
return await get_latest_stable_nextflow_release(releases)
|
||||
}
|
||||
|
||||
// The releases are sent in reverse chronological order
|
||||
// If we are sent a numbered tag, then back through the list until we find
|
||||
// a release that fulfils the requested version number
|
||||
for await (const release of releases) {
|
||||
if (semver.satisfies(release.versionNumber, version, true)) {
|
||||
if (semver.satisfies(release.version, version, true)) {
|
||||
return release
|
||||
}
|
||||
}
|
||||
|
@ -127,8 +27,8 @@ export async function install_nextflow(
|
|||
release: NextflowRelease,
|
||||
get_all: boolean
|
||||
): Promise<string> {
|
||||
const url = get_all ? release.allBinaryURL : release.binaryURL
|
||||
const version = release.versionNumber
|
||||
const url = get_all ? release.downloadUrlAll : release.downloadUrl
|
||||
const version = release.version
|
||||
|
||||
core.debug(`Downloading Nextflow from ${url}`)
|
||||
const nf_dl_path = await retry(
|
||||
|
|
27
src/main.ts
27
src/main.ts
|
@ -11,10 +11,9 @@ import {
|
|||
} from "./functions"
|
||||
import { NextflowRelease } from "./nextflow-release"
|
||||
import {
|
||||
pull_latest_stable_release,
|
||||
pull_releases,
|
||||
setup_octokit
|
||||
} from "./octokit-wrapper"
|
||||
get_latest_nextflow_version,
|
||||
get_nextflow_versions
|
||||
} from "./nf-core-api-wrapper"
|
||||
|
||||
async function run(): Promise<void> {
|
||||
// CAPSULE_LOG leads to a bunch of boilerplate being output to the logs: turn
|
||||
|
@ -22,33 +21,29 @@ async function run(): Promise<void> {
|
|||
core.exportVariable("CAPSULE_LOG", "none")
|
||||
|
||||
// Read in the arguments
|
||||
const token = core.getInput("token")
|
||||
const version = core.getInput("version")
|
||||
const get_all = core.getBooleanInput("all")
|
||||
const cooldown = Number(core.getInput("cooldown"))
|
||||
const max_retries = Number(core.getInput("max-retries"))
|
||||
|
||||
// Check the cache for the Nextflow version that matched last time
|
||||
if (check_cache(version)) {
|
||||
return
|
||||
}
|
||||
|
||||
// Setup the API
|
||||
const octokit = await setup_octokit(token, cooldown, max_retries)
|
||||
|
||||
// Get the release info for the desired release
|
||||
let release = {} as NextflowRelease
|
||||
let resolved_version = ""
|
||||
try {
|
||||
if (version === "latest" || version === "latest-stable") {
|
||||
release = await pull_latest_stable_release(octokit)
|
||||
if (version.includes("latest")) {
|
||||
let flavor = version.split("-")[1]
|
||||
flavor = flavor ? flavor : "stable"
|
||||
release = await get_latest_nextflow_version(flavor)
|
||||
} else {
|
||||
const release_iterator = pull_releases(octokit)
|
||||
release = await get_nextflow_release(version, release_iterator)
|
||||
const nextflow_releases = await get_nextflow_versions()
|
||||
release = await get_nextflow_release(version, nextflow_releases)
|
||||
}
|
||||
resolved_version = release.versionNumber
|
||||
resolved_version = release.version
|
||||
core.info(
|
||||
`Input version '${version}' resolved to Nextflow ${release["name"]}`
|
||||
`Input version '${version}' resolved to Nextflow ${release.version}`
|
||||
)
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
|
|
|
@ -2,48 +2,9 @@
|
|||
* Houses the pertinent data that GitHub exposes for each Nextflow release
|
||||
*/
|
||||
export type NextflowRelease = {
|
||||
versionNumber: string
|
||||
version: string
|
||||
isEdge: boolean
|
||||
binaryURL: string
|
||||
allBinaryURL: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the raw OctoKit data into a structured NextflowRelease
|
||||
* @param data A "release" data struct from OctoKit
|
||||
* @returns `data` converted into a `NextflowRelease`
|
||||
*/
|
||||
export function nextflow_release(data: object): NextflowRelease {
|
||||
const nf_release: NextflowRelease = {
|
||||
versionNumber: data["tag_name"],
|
||||
isEdge: data["prerelease"],
|
||||
binaryURL: nextflow_bin_url(data, false),
|
||||
allBinaryURL: nextflow_bin_url(data, true)
|
||||
}
|
||||
return nf_release
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the download URL of a Nextflow binary
|
||||
* @param release A "release" data struct from OctoKit
|
||||
* @param get_all Whether to return the url for the "all" variant of Nextflow
|
||||
* @returns The URL of the Nextflow binary
|
||||
*/
|
||||
export function nextflow_bin_url(release: object, get_all: boolean): string {
|
||||
const release_assets = release["assets"]
|
||||
const all_asset = release_assets.filter((a: object) => {
|
||||
return a["browser_download_url"].endsWith("-all")
|
||||
})[0]
|
||||
const regular_asset = release_assets.filter((a: object) => {
|
||||
return a["name"] === "nextflow"
|
||||
})[0]
|
||||
|
||||
const dl_asset = get_all ? all_asset : regular_asset
|
||||
if (dl_asset) {
|
||||
return dl_asset.browser_download_url
|
||||
} else {
|
||||
// Old pre-release versions of Nextflow didn't have an "all" variant. To
|
||||
// avoid downstream errors, substitute the regular url here.
|
||||
return regular_asset.browser_download_url
|
||||
}
|
||||
downloadUrl: string
|
||||
downloadUrlAll: string
|
||||
published_at?: string
|
||||
}
|
||||
|
|
45
src/nf-core-api-wrapper.ts
Normal file
45
src/nf-core-api-wrapper.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { info } from "@actions/core"
|
||||
import { downloadTool } from "@actions/tool-cache"
|
||||
import retry from "async-retry"
|
||||
import { readFileSync } from "fs"
|
||||
|
||||
import { NextflowRelease } from "./nextflow-release"
|
||||
|
||||
async function fetch_nextflow_versions_data(): Promise<object> {
|
||||
// Occasionally the connection is reset for unknown reasons
|
||||
// In those cases, retry the download
|
||||
const versionsFile = await retry(
|
||||
async () => {
|
||||
return await downloadTool("https://nf-co.re/nextflow_version")
|
||||
},
|
||||
{
|
||||
retries: 5,
|
||||
onRetry: (err: Error) => {
|
||||
info(`Download of versions.json failed, trying again. Error: ${err}`)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return JSON.parse(readFileSync(versionsFile).toString())
|
||||
}
|
||||
|
||||
export async function get_nextflow_versions(): Promise<NextflowRelease[]> {
|
||||
const version_dataset = await fetch_nextflow_versions_data()
|
||||
const versions = version_dataset["versions"]
|
||||
const nextflow_releases: NextflowRelease[] = []
|
||||
// eslint-disable-next-line github/array-foreach
|
||||
versions.array.forEach(element => {
|
||||
const release = element as NextflowRelease
|
||||
nextflow_releases.push(release)
|
||||
})
|
||||
return nextflow_releases
|
||||
}
|
||||
|
||||
export async function get_latest_nextflow_version(
|
||||
flavor: string
|
||||
): Promise<NextflowRelease> {
|
||||
const version_dataset = await fetch_nextflow_versions_data()
|
||||
const latest_versions = version_dataset["latest"]
|
||||
const latest_version = latest_versions[flavor] as NextflowRelease
|
||||
return latest_version
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
import * as core from "@actions/core"
|
||||
import { getOctokitOptions, GitHub } from "@actions/github/lib/utils"
|
||||
import { throttling } from "@octokit/plugin-throttling"
|
||||
|
||||
import { nextflow_release, NextflowRelease } from "./nextflow-release"
|
||||
|
||||
const NEXTFLOW_REPO = {
|
||||
owner: "nextflow-io",
|
||||
repo: "nextflow",
|
||||
per_page: 100,
|
||||
headers: {
|
||||
"x-github-api-version": "2022-11-28"
|
||||
}
|
||||
}
|
||||
|
||||
export async function setup_octokit(
|
||||
github_token: string,
|
||||
cooldown = 60,
|
||||
max_retries = 3
|
||||
): Promise<InstanceType<typeof GitHub>> {
|
||||
const throttledOctokit = GitHub.plugin(throttling)
|
||||
let octokit = {} as InstanceType<typeof GitHub>
|
||||
try {
|
||||
octokit = new throttledOctokit(
|
||||
getOctokitOptions(github_token, {
|
||||
throttle: {
|
||||
onRateLimit: (retryAfter, options, ok, retryCount) => {
|
||||
ok.log.warn(
|
||||
`Request quota exhausted for request ${options.method} ${options.url}`
|
||||
)
|
||||
|
||||
if (retryCount < max_retries) {
|
||||
ok.log.info(`Retrying after ${retryAfter} seconds!`)
|
||||
return true
|
||||
}
|
||||
},
|
||||
onSecondaryRateLimit: (retryAfter, options, ok, retryCount) => {
|
||||
ok.log.warn(
|
||||
`SecondaryRateLimit detected for request ${options.method} ${options.url}`
|
||||
)
|
||||
|
||||
if (retryCount < max_retries) {
|
||||
octokit.log.info(`Retrying after ${retryAfter} seconds!`)
|
||||
return true
|
||||
}
|
||||
},
|
||||
fallbackSecondaryRateRetryAfter: cooldown
|
||||
}
|
||||
})
|
||||
)
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
core.setFailed(
|
||||
`Could not authenticate to GitHub Releases API with provided token\n${e.message}`
|
||||
)
|
||||
}
|
||||
}
|
||||
return octokit
|
||||
}
|
||||
|
||||
export async function* pull_releases(
|
||||
octokit: InstanceType<typeof GitHub>
|
||||
): AsyncGenerator<NextflowRelease> {
|
||||
const iterator = octokit.paginate.iterator(
|
||||
octokit.rest.repos.listReleases,
|
||||
NEXTFLOW_REPO
|
||||
)
|
||||
let item_index = 0
|
||||
let release_items = []
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/unbound-method */
|
||||
const { next } = iterator[Symbol.asyncIterator]()
|
||||
|
||||
let request = await next()
|
||||
release_items = request.value.data
|
||||
|
||||
while (true) {
|
||||
if (item_index > release_items.length) {
|
||||
request = await next()
|
||||
release_items = request.value.data
|
||||
item_index = 0
|
||||
}
|
||||
yield nextflow_release(release_items[item_index++])
|
||||
}
|
||||
}
|
||||
|
||||
export async function pull_latest_stable_release(
|
||||
ok: InstanceType<typeof GitHub>
|
||||
): Promise<NextflowRelease> {
|
||||
const { data: stable_release } = await ok.rest.repos.getLatestRelease(
|
||||
NEXTFLOW_REPO
|
||||
)
|
||||
|
||||
return nextflow_release(stable_release)
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import test from "ava" // eslint-disable-line import/no-unresolved
|
||||
import test from "ava" //eslint-disable-line import/no-unresolved
|
||||
import { execSync } from "child_process"
|
||||
|
||||
import * as functions from "../src/functions"
|
||||
import { get_nextflow_release, install_nextflow } from "../src/functions"
|
||||
import { NextflowRelease } from "../src/nextflow-release"
|
||||
|
||||
// The Nextflow releases we are going to use for testing follow a regular
|
||||
|
@ -9,10 +10,10 @@ import { NextflowRelease } from "../src/nextflow-release"
|
|||
function nf_release_gen(version_number: string): NextflowRelease {
|
||||
const is_edge = version_number.endsWith("-edge")
|
||||
const release: NextflowRelease = {
|
||||
versionNumber: version_number,
|
||||
version: version_number,
|
||||
isEdge: is_edge,
|
||||
binaryURL: `https://github.com/nextflow-io/nextflow/releases/download/${version_number}/nextflow`,
|
||||
allBinaryURL: `https://github.com/nextflow-io/nextflow/releases/download/${version_number}/nextflow-${version_number.replace(
|
||||
downloadUrl: `https://github.com/nextflow-io/nextflow/releases/download/${version_number}/nextflow`,
|
||||
downloadUrlAll: `https://github.com/nextflow-io/nextflow/releases/download/${version_number}/nextflow-${version_number.replace(
|
||||
"v",
|
||||
""
|
||||
)}-all`
|
||||
|
@ -20,95 +21,85 @@ function nf_release_gen(version_number: string): NextflowRelease {
|
|||
return release
|
||||
}
|
||||
|
||||
// A mock set of Nextflow releases
|
||||
async function* edge_is_newer(): AsyncGenerator<NextflowRelease> {
|
||||
yield nf_release_gen("v23.09.1-edge")
|
||||
yield nf_release_gen("v23.04.3")
|
||||
yield nf_release_gen("v23.04.2")
|
||||
}
|
||||
|
||||
async function* edge_is_older(): AsyncGenerator<NextflowRelease> {
|
||||
yield nf_release_gen("v23.04.3")
|
||||
yield nf_release_gen("v23.04.2")
|
||||
yield nf_release_gen("v23.03.0-edge")
|
||||
}
|
||||
|
||||
/*
|
||||
The whole reason this action exists is to handle the cases where a final
|
||||
release is the "bleeding edge" release, rather than the "edge" release, even
|
||||
though that's what the name would imply. Therefore, we need to test that the
|
||||
'latest-everything' parameter can find the correct one regardless of whether
|
||||
an "edge" release or a stable release is the true latest
|
||||
*/
|
||||
const release_filter_macro = test.macro(
|
||||
const release_test_macro = test.macro(
|
||||
async (
|
||||
t,
|
||||
input_version: string,
|
||||
expected_version: string,
|
||||
releases: AsyncGenerator<NextflowRelease>
|
||||
is_edge_older: Boolean
|
||||
) => {
|
||||
const matched_release = await functions.get_nextflow_release(
|
||||
const releases_set = [
|
||||
nf_release_gen("v21.05.1-edge"),
|
||||
nf_release_gen("v21.05.0-edge"),
|
||||
nf_release_gen("v21.04.2"),
|
||||
nf_release_gen("v21.04.1"),
|
||||
nf_release_gen("v21.04.0"),
|
||||
nf_release_gen("v21.03.0-edge")
|
||||
]
|
||||
const release_filtered = releases_set.splice(is_edge_older ? 2 : 0)
|
||||
const matched_release = await get_nextflow_release(
|
||||
input_version,
|
||||
releases
|
||||
release_filtered
|
||||
)
|
||||
t.is(matched_release.versionNumber, expected_version)
|
||||
t.is(matched_release.version, expected_version)
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
"Latest-everything install with newer edge release",
|
||||
release_filter_macro,
|
||||
"latest-everything",
|
||||
"v23.09.1-edge",
|
||||
edge_is_newer()
|
||||
"Major and minor version only (edge newer)",
|
||||
release_test_macro,
|
||||
"v21.04",
|
||||
"v21.04.2",
|
||||
false
|
||||
)
|
||||
test(
|
||||
"Latest-everything install with older edge release",
|
||||
release_filter_macro,
|
||||
"latest-everything",
|
||||
"v23.04.3",
|
||||
edge_is_older()
|
||||
"Major and minor version only (edge older)",
|
||||
release_test_macro,
|
||||
"v21.04",
|
||||
"v21.04.2",
|
||||
true
|
||||
)
|
||||
test(
|
||||
"Latest-edge install with newer edge release",
|
||||
release_filter_macro,
|
||||
"latest-edge",
|
||||
"v23.09.1-edge",
|
||||
edge_is_newer()
|
||||
"Major, minor, and patch version: latest patch (edge newer)",
|
||||
release_test_macro,
|
||||
"v21.04.2",
|
||||
"v21.04.2",
|
||||
false
|
||||
)
|
||||
test(
|
||||
"Latest-edge install with older edge release",
|
||||
release_filter_macro,
|
||||
"latest-edge",
|
||||
"v23.03.0-edge",
|
||||
edge_is_older()
|
||||
"Major, minor, and patch version: latest patch (edge older)",
|
||||
release_test_macro,
|
||||
"v21.04.2",
|
||||
"v21.04.2",
|
||||
true
|
||||
)
|
||||
test(
|
||||
"Latest-stable install with newer edge release",
|
||||
release_filter_macro,
|
||||
"latest",
|
||||
"v23.04.3",
|
||||
edge_is_newer()
|
||||
"Major, minor, and patch version: older patch (edge newer)",
|
||||
release_test_macro,
|
||||
"v21.04.1",
|
||||
"v21.04.1",
|
||||
false
|
||||
)
|
||||
test(
|
||||
"Latest-stable install with older edge release",
|
||||
release_filter_macro,
|
||||
"latest",
|
||||
"v23.04.3",
|
||||
edge_is_older()
|
||||
"Major, minor, and patch version: older patch (edge older)",
|
||||
release_test_macro,
|
||||
"v21.04.1",
|
||||
"v21.04.1",
|
||||
true
|
||||
)
|
||||
test(
|
||||
"Fully versioned tag release",
|
||||
release_filter_macro,
|
||||
"v23.04.2",
|
||||
"v23.04.2",
|
||||
edge_is_newer()
|
||||
)
|
||||
test(
|
||||
"Partially versioned tag release",
|
||||
release_filter_macro,
|
||||
"v23.04",
|
||||
"v23.04.3",
|
||||
edge_is_newer()
|
||||
"Edge release",
|
||||
release_test_macro,
|
||||
"v21.03.0-edge",
|
||||
"v21.03.0-edge",
|
||||
false
|
||||
)
|
||||
|
||||
test.todo("install_nextflow")
|
||||
test("Install Nextflow", async t => {
|
||||
const release = nf_release_gen("v23.10.1")
|
||||
const install_dir = await install_nextflow(release, false)
|
||||
|
||||
const version_output = execSync(`${install_dir}/nextflow -v`).toString()
|
||||
const version_regex = /nextflow version 23\.10\.1.*/
|
||||
t.regex(version_output, version_regex)
|
||||
})
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
import * as github from "@actions/github"
|
||||
import { GitHub } from "@actions/github/lib/utils"
|
||||
import anyTest, { TestFn } from "ava" // eslint-disable-line import/no-unresolved
|
||||
|
||||
import { NextflowRelease } from "../src/nextflow-release"
|
||||
import {
|
||||
pull_latest_stable_release,
|
||||
pull_releases
|
||||
} from "../src/octokit-wrapper"
|
||||
import { getToken } from "./utils"
|
||||
|
||||
const test = anyTest as TestFn<{
|
||||
token: string
|
||||
octokit: InstanceType<typeof GitHub>
|
||||
}>
|
||||
|
||||
test.before(t => {
|
||||
const first = true
|
||||
const current_token = getToken(first)
|
||||
t.context = {
|
||||
token: current_token,
|
||||
octokit: github.getOctokit(current_token)
|
||||
}
|
||||
})
|
||||
|
||||
async function get_latest_release(
|
||||
octokit: InstanceType<typeof GitHub>,
|
||||
use_latest_api: boolean
|
||||
): Promise<NextflowRelease> {
|
||||
if (use_latest_api) {
|
||||
return await pull_latest_stable_release(octokit)
|
||||
} else {
|
||||
const all_releases = pull_releases(octokit)
|
||||
const first_response = await all_releases.next()
|
||||
const first_release = first_response.value
|
||||
? first_response.value
|
||||
: ({} as NextflowRelease)
|
||||
return first_release
|
||||
}
|
||||
}
|
||||
|
||||
const version_macro = test.macro(
|
||||
async (t, object_name: string, use_latest_api: boolean) => {
|
||||
const latest_release = await get_latest_release(
|
||||
t.context.octokit,
|
||||
use_latest_api
|
||||
)
|
||||
t.assert(latest_release[object_name])
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
"OctoKit iterator returns semver-parsable version number",
|
||||
version_macro,
|
||||
"versionNumber",
|
||||
false
|
||||
)
|
||||
test(
|
||||
"OctoKit latest API returns semver-parable version number",
|
||||
version_macro,
|
||||
"versionNumber",
|
||||
true
|
||||
)
|
||||
|
||||
const binary_url_macro = test.macro(
|
||||
async (t, get_all: boolean, use_latest_api: boolean) => {
|
||||
const latest_release = await get_latest_release(
|
||||
t.context.octokit,
|
||||
use_latest_api
|
||||
)
|
||||
const url = get_all ? latest_release.allBinaryURL : latest_release.binaryURL
|
||||
t.notThrows(() => new URL(url))
|
||||
}
|
||||
)
|
||||
|
||||
test("Nextflow binary URL from iterator valid", binary_url_macro, false, false)
|
||||
test("Nextflow binary URL from latest API valid", binary_url_macro, false, true)
|
||||
test(
|
||||
"Nextflow all binary URL from iterator valid",
|
||||
binary_url_macro,
|
||||
true,
|
||||
false
|
||||
)
|
||||
test(
|
||||
"Nextflow all binary URL from latest API valid",
|
||||
binary_url_macro,
|
||||
true,
|
||||
true
|
||||
)
|
|
@ -1,12 +0,0 @@
|
|||
export function getToken(first: boolean): string {
|
||||
const token = process.env["GITHUB_TOKEN"] || ""
|
||||
if (!token && first) {
|
||||
/* eslint-disable-next-line no-console */
|
||||
console.warn(
|
||||
"Skipping GitHub tests. Set $GITHUB_TOKEN to run REST client and GraphQL client tests"
|
||||
)
|
||||
first = false
|
||||
}
|
||||
|
||||
return token
|
||||
}
|
|
@ -6,7 +6,9 @@
|
|||
"outDir": "./lib",
|
||||
"strict": true,
|
||||
"noImplicitAny": false,
|
||||
"esModuleInterop": true
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true,
|
||||
"lib": ["esnext", "dom"]
|
||||
},
|
||||
"include": ["src/**/*", "test/**/*"],
|
||||
"exclude": ["node_modules", "**/*.test.ts"]
|
||||
|
|
Loading…
Reference in a new issue