Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch out the API #37

Merged
merged 24 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
56ce05e
feat: Add optional published_at field to NextflowRelease type
MillironX Feb 2, 2024
fff8d35
feat: Add nf-core website API wrapper
MillironX Feb 2, 2024
aa8fcde
feat: Make get_nextflow_release compatible with arrays
MillironX Feb 2, 2024
8bfbe1c
test!: Remove version resolving tests for "latest*" versions
MillironX Feb 2, 2024
8ca0410
fix: Fix the version number debug log
MillironX Feb 2, 2024
daf4cf1
feat!: Remove the "latest-*" version resolvers from get_nextflow_release
MillironX Feb 2, 2024
984a087
refactor!: Rename NextflowRelease.versionNumber to NextflowRelease.ve…
MillironX Feb 2, 2024
3f6d80f
refactor!: Rename NextflowRelease.binaryURL to NextflowRelease.downlo…
MillironX Feb 2, 2024
4f4014a
refactor!: Rename NextflowRelease.allBinaryURL to NextflowRelease.dow…
MillironX Feb 2, 2024
0198d4c
refactor!: Replace Octokit API with nf-core API in main script
MillironX Feb 2, 2024
fbfe28d
feat!: Remove Octokit API
MillironX Feb 2, 2024
ee9581e
chore!: Remove octokit throttling dependency
MillironX Feb 2, 2024
1503f70
test!: Remove testing utils for getting GitHub token
MillironX Feb 3, 2024
fdbadcc
feat!: Remove Octkit conversion function for NextflowRelease
MillironX Feb 3, 2024
b12a1f1
feat!: Remove url resolver for NextflowRelease
MillironX Feb 3, 2024
6fc214b
test: Add tests for Nextflow release version resolver
MillironX Feb 3, 2024
8f846c0
chore: Add ability to deal with temporary files generated by tests
MillironX Feb 3, 2024
fefc68e
test: Add test for install_nextflow
MillironX Feb 3, 2024
90a761f
chore!: Remove unused parameters from action.yml
MillironX Feb 3, 2024
f834f9d
chore: Update CHANGELOG
MillironX Feb 3, 2024
920e629
chore: Remove GitHub token from README
MillironX Feb 3, 2024
b4eb157
chore: Remove GITHUB_TOKEN from actrc
MillironX Feb 3, 2024
dbb117b
chore: Remove unused parameters from debug configuration
MillironX Feb 4, 2024
92e953d
fix: Increase ava test timeout amount
MillironX Mar 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .actrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
-P ubuntu-latest=catthehacker/ubuntu:act-latest
-s GITHUB_TOKEN
--container-architecture linux/amd64
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,8 @@ dist

# Ignore built ts files
__tests__/runner/*
lib/**/*
lib/**/*

# Testing garbage
.tmp
nxf-v*
5 changes: 1 addition & 4 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@
"outFiles": ["${workspaceFolder}/lib/**/*.js"],
"env": {
"INPUT_ALL": "false",
"INPUT_VERSION": "latest",
"INPUT_TOKEN": "${env:GITHUB_TOKEN}",
"INPUT_COOLDOWN": "60",
"INPUT_MAX_RETRIES": "3",
"INPUT_VERSION": "v23.10",
"RUNNER_TEMP": "${workspaceFolder}/.tmp"
}
}
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Husky pre-commit hooks for linting and formatting
- Deprecation messages to warn users of upcoming API switch

### Changed

- GitHub Octokit API switched to nf-core custom API

## [1.5.1] - 2024-01-30

### Changed
Expand Down
11 changes: 0 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,6 @@ There are three (technically four) aliases to assist in choosing up-to-date Next

A boolean deciding whether to download the "all versions" distribution of Nextflow. May be useful for running tests against multiple versions downstream.

### `token`

> **default: `${{ secrets.GITHUB_TOKEN }}`**

> **:warning: This really shouldn't be changed. If you think this will fix a workflow problem, triple-check everything else first. :warning:**

This action locates the releases based upon the GitHub API, and requires an access token. The default token provided with all GitHub actions should be sufficient for all use cases on GitHub. Valid reasons to change this:

- GitHub Enterprise server (and only under some configurations)
- Testing workflows locally with [act](https://github.com/nektos/act)

## Outputs

There are no outputs from this action.
Expand Down
16 changes: 0 additions & 16 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +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 }}
deprecationMessage: "setup-nextflow@v2 will no longer use the GitHub API. A token will no longer be needed."
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"
deprecationMessage: "setup-nextflow@v2 will no longer use the GitHub API. The cooldown will no longer apply."
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"
deprecationMessage: "setup-nextflow@v2 will no longer use the GitHub API. The retry count will no longer apply."

runs:
using: "node20"
main: "dist/index.js"
Expand Down
37 changes: 1 addition & 36 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
"extensions": [
"ts"
],
"environmentVariables": {
"RUNNER_TEMP": "./.tmp"
},
"rewritePaths": {
"src/": "lib/"
},
Expand All @@ -43,15 +46,15 @@
],
"concurrency": 1,
"serial": true,
"powerAssert": true
"powerAssert": true,
"timeout": "120s"
},
"license": "MIT",
"dependencies": {
"@actions/core": "^1.8.2",
"@actions/exec": "^1.1.1",
"@actions/github": "^6.0.0",
"@actions/tool-cache": "^2.0.1",
"@octokit/plugin-throttling": "^8.1.3",
"@types/node": "^20.0.0",
"async-retry": "^1.3.3",
"semver": "^7.3.7"
Expand Down
108 changes: 4 additions & 104 deletions src/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand All @@ -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(
Expand Down
27 changes: 11 additions & 16 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,39 @@ 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
// it off
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) {
Expand Down
Loading