Skip to content

Commit

Permalink
✨ Add support for semver groovy version ranges (#4)
Browse files Browse the repository at this point in the history
You now can specify groovy-versions such as:
- '4.x'
- '4.0.x'
- '<4.0.0'
- '>=3.x <4.0.0'
  • Loading branch information
WtfJoke authored Feb 14, 2023
1 parent 6474f53 commit 0a0217c
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ jobs:
- uses: actions/checkout@v3
- uses: ./
with:
groovy-version: 4.0.9
groovy-version: 4.x
- name: Display groovy version
run: groovy --version
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,41 @@ This action can be run on `ubuntu-latest`, `windows-latest`, and `macos-latest`
steps:
- uses: wtfjoke/setup-groovy@v1
with:
groovy-version: '4.0.9'
groovy-version: '4.x'
- run: groovy --version
```
## 📊 Supported version syntax
If there is a specific version of Groovy that you need and you don't want to worry about any potential breaking changes due to patch updates (going from `4.0.8` to `4.0.9` for example), you should specify the **exact major, minor, and patch version** (such as `4.0.9`):

```yaml
steps:
- uses: actions/checkout@v3
- uses: wtfjoke/setup-groovy@v1
with:
groovy-version: '4.0.9'
- run: groovy HelloWorld.groovy
```

You can specify **only a major and minor version** if you are okay with the most recent patch version being used:

```yaml
steps:
- uses: actions/checkout@v3
- uses: wtfjoke/setup-groovy@v1
with:
groovy-version: '4.0'
- run: groovy HelloWorld.groovy
```

You can also use ranges that are specified in [semver](https://github.com/npm/node-semver#ranges), for example a [hypen-range](https://github.com/npm/node-semver#advanced-range-syntax):

```yaml
steps:
- uses: actions/checkout@v3
- uses: wtfjoke/setup-groovy@v1
with:
groovy-version: '>=3.x <4.0.0'
- run: groovy HelloWorld.groovy
```
21 changes: 17 additions & 4 deletions __tests__/release.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {isReleaseAvailable, fetchAvailableVersions} from '../src/release'
import {fetchAvailableVersions, getMatchingVersion} from '../src/release'

describe('release', () => {
it('should fetch versions', async () => {
Expand All @@ -8,8 +8,21 @@ describe('release', () => {
expect(versions).toContain('4.0.9')
})

it("should fetch releases for '4.0.9'", async () => {
const releases = await isReleaseAvailable('4.0.9')
expect(releases).toBe(true)
it("should find the latest version that satisfies '2.x'", async () => {
const version = await getMatchingVersion('2.x')
expect(version).toBeDefined()
expect(version).toBe('2.5.21')
})

it('should find latest 2.x releases when excluding 3.0.0', async () => {
const version = await getMatchingVersion('>=2.x <3.0.0')
expect(version).toBeDefined()
expect(version).toBe('2.5.21')
})

it('should find 4.0.0-rc-2 pre-release', async () => {
const version = await getMatchingVersion('4.0.0-rc-2')
expect(version).toBeDefined()
expect(version).toBe('4.0.0-rc-2')
})
})
4 changes: 2 additions & 2 deletions __tests__/setup-groovy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as core from '@actions/core'
import {existsSync} from 'fs'
import {rm} from 'fs/promises'
import path from 'path'
import {setupGroovy, setupGroovyVersion} from '../src/setup-groovy'
import {setupGroovy} from '../src/setup-groovy'

const tempDir = path.join(__dirname, 'runner', 'temp')
process.env['RUNNER_TEMP'] = tempDir
Expand All @@ -18,7 +18,7 @@ describe('setup-groovy', () => {
jest.resetAllMocks()
})

it.each(['4.0.9', '1.1-beta-2'])(
it.each(['4.0.9', '4.0.0-rc-2', '1.8.0-beta-1'])(
"should setup groovy '%s'",
async version => {
const groovyExecutableFolderName = path.join(`groovy-${version}`, 'bin')
Expand Down
3 changes: 2 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ author: 'WtfJoke (Manuel)'

inputs:
groovy-version:
description: 'The version of Groovy to install. Takes a whole or semver Groovy version'
description: 'The version of Groovy to install. Exact version or version range of Groovy. Using semver version range syntax. Examples: 4.x, 4.0.x, 4.0.9, 4.0.0-rc-1, etc.'
required: true
runs:
using: 'node16'
main: 'dist/index.js'
Expand Down
22 changes: 11 additions & 11 deletions dist/index.js

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

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions src/release.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {HttpClient} from '@actions/http-client'
import {debug} from '@actions/core'
import {XMLParser} from 'fast-xml-parser'
import {maxSatisfying} from 'semver'

const GROOVY_OLDER_RELEASES_URL =
'https://repo1.maven.org/maven2/org/codehaus/groovy/groovy/maven-metadata.xml'
Expand Down Expand Up @@ -28,11 +29,13 @@ const http = new HttpClient('setup-groovy', undefined, {
})
const parser = new XMLParser()

export const isReleaseAvailable = async (version: string) => {
export const getMatchingVersion = async (
versionRange: string
): Promise<string | null> => {
debug(`Fetching groovy releases for Groovy version '${versionRange}'`)
const versions = await fetchAvailableVersions()
debug(`Available versions: ${JSON.stringify(versions)})`)
const isVersionAvailable = versions.includes(version)
return isVersionAvailable
return maxSatisfying(versions, versionRange)
}

export const fetchAvailableVersions = async () => {
Expand Down
13 changes: 6 additions & 7 deletions src/setup-groovy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {getInput, debug, addPath, error as coreError} from '@actions/core'
import {downloadTool, extractZip} from '@actions/tool-cache'
import {coerce, lt} from 'semver'
import {isReleaseAvailable} from './release'
import {getMatchingVersion} from './release'

const GROOVY_BASE_URL =
'https://groovy.jfrog.io/artifactory/dist-release-local/groovy-zips'
Expand All @@ -20,15 +20,14 @@ export const setupGroovy = async () => {
}

export const setupGroovyVersion = async (version: string) => {
debug(`Fetching groovy releases for Groovy version '${version}'`)
const isVersionAvailable = await isReleaseAvailable(version)
if (!isVersionAvailable) {
throw new Error(`Unable to find Groovy version '${version}'`)
const matchingVersion = await getMatchingVersion(version)
if (!matchingVersion) {
throw new Error(`Unable to find matching Groovy version for: '${version}'`)
}
const groovyBinaryFileName = getFileName(version)
const groovyBinaryFileName = getFileName(matchingVersion)
const url = `${GROOVY_BASE_URL}/${groovyBinaryFileName}`
const groovyRootPath = await downloadGroovy(url)
const groovyBinaryPath = `${groovyRootPath}/groovy-${version}/bin`
const groovyBinaryPath = `${groovyRootPath}/groovy-${matchingVersion}/bin`
debug(`Adding '${groovyBinaryPath}' to PATH`)
addPath(groovyBinaryPath)
return groovyBinaryPath
Expand Down

0 comments on commit 0a0217c

Please sign in to comment.