Skip to content

Commit

Permalink
Add allow-prerelease option
Browse files Browse the repository at this point in the history
When using check-only to confirm if a version already exists, this update allows you to optionally ignore prerelease version conflicts. E.g. if v1.2.3-SNAPSHOT exists in the repository tags, running this action with check-only and allow-prerelase both set to true will pass.
  • Loading branch information
ncalteen committed May 14, 2024
1 parent 0427ad5 commit fb19df4
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 31 deletions.
38 changes: 21 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,27 @@ jobs:
## Inputs
| Input | Description |
| --------------- | ---------------------------------------------------------- |
| `check-only` | If set to `'true'`, only checks if the version exists. |
| | Causes the action to fail if the version already exists. |
| | Default: `'false'` |
| `manifest-path` | The path to the manifest file that contains the version. |
| | Relative to the root of the repository. |
| | If not set, `use-version` must be set. |
| `overwrite` | Set to `'true'` for the action to overwrite existing tags. |
| | Default: `'false'` |
| `ref` | The Git ref to tag with the specified or inferred version. |
| | Defaults to the base ref of a pull request event trigger. |
| `use-version` | The version you want to explicitly use. |
| | This must follow SemVer 2.0 standards. |
| | If not set, `manifest-path` must be set. |
| `workspace` | The path where the repository has been cloned. |
| | Default: `${{ github.workspace }}` for `actions/checkout`. |
| Input | Description |
| ------------------ | ------------------------------------------------------ |
| `allow-prerelease` | If `check-only` is `'true'`, this controls if the |
| | check should pass if a matching prerelease version is |
| | detected (e.g. `v1.0.0-SNAPSHOT`) |
| | Default: `'true'` |
| `check-only` | If set to `'true'`, only checks if the version exists. |
| | Fails the action if the version already exists. |
| | Default: `'false'` |
| `manifest-path` | The path to the manifest that contains the version. |
| | Relative to the root of the repository. |
| | If not set, `use-version` must be set. |
| `overwrite` | Set to `'true'` to overwrite existing tags. |
| | Default: `'false'` |
| `ref` | The Git ref to tag. |
| | Defaults to the base ref of a pull request trigger. |
| `use-version` | The version you want to explicitly use. |
| | This must follow SemVer 2.0 standards. |
| | If not set, `manifest-path` must be set. |
| `workspace` | The path where the repository has been cloned. |
| | Default: `${{ github.workspace }}` |

## Outputs

Expand Down
29 changes: 27 additions & 2 deletions __tests__/version.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,9 @@ describe('version', () => {

const version = new Version('1.2.3-alpha.4')

expect(await version.exists(`${__dirname}/fixtures/valid`)).toBe(true)
expect(await version.exists(`${__dirname}/fixtures/valid`, false)).toBe(
true
)
})

it('exists returns false if the tag does not exist', async () => {
Expand All @@ -656,6 +658,29 @@ describe('version', () => {

const version = new Version('1.2.3-alpha.4')

expect(await version.exists(`${__dirname}/fixtures/valid`)).toBe(false)
expect(await version.exists(`${__dirname}/fixtures/valid`, false)).toBe(
false
)
})

it('exists returns false if the tag exists but prereleases are allowed', async () => {
// Mock the exec package to return the tag
const execMock = exec as jest.MockedFunction<typeof exec>
execMock.mockImplementation(
(
commandLine: string,
args?: string[],
options?: any
): Promise<number> => {
options.listeners.stdout(Buffer.from('1.2.3-alpha.4'))
return Promise.resolve(0)
}
)

const version = new Version('1.2.3-alpha.4')

expect(await version.exists(`${__dirname}/fixtures/valid`, true)).toBe(
false
)
})
})
6 changes: 6 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ branding:
color: blue

inputs:
allow-prerelease:
default: 'true'
description:
When `check-only` is set to 'true', this will allow prerelease versions to
pass. Defaults to 'true'.
required: false
check-only:
default: 'false'
description:
Expand Down
14 changes: 10 additions & 4 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.

4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "semver",
"description": "Semantically version GitHub repository tags",
"version": "1.1.1",
"version": "1.2.0",
"author": "Nick Alteen <ncalteen@github.com>",
"homepage": "https://github.com/issue-ops/semver#readme",
"repository": {
Expand Down
6 changes: 4 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as core from '@actions/core'
import { Version } from './version'

export async function run() {
const allowPrerelease: boolean = core.getInput('allow-prerelease') === 'true'
const checkOnly: boolean = core.getInput('check-only') === 'true'
const manifestPath: string = core.getInput('manifest-path')
const overwrite: boolean = core.getInput('overwrite') === 'true'
Expand All @@ -16,6 +17,7 @@ export async function run() {
return core.setFailed('Must provide manifest-path OR use-version')

core.info('Running action with inputs:')
core.info(`\tAllow Prerelease: ${allowPrerelease}`)
core.info(`\tCheck: ${checkOnly}`)
core.info(`\tManifest Path: ${manifestPath}`)
core.info(`\tOverwrite: ${overwrite}`)
Expand All @@ -31,11 +33,11 @@ export async function run() {
if (version === undefined) return core.setFailed('Could not infer version')

// Stop now if we're only checking the version.
if (checkOnly && (await version.exists(workspace)))
if (checkOnly && (await version.exists(workspace, allowPrerelease)))
return core.setFailed("Version already exists and 'check-only' is true")

// Check if the tags already exist in the repository.
if (!checkOnly && !overwrite && (await version.exists(workspace)))
if (!checkOnly && !overwrite && (await version.exists(workspace, false)))
return core.setFailed("Version already exists and 'overwrite' is false")

core.info(`Inferred Version: ${version.toString()}`)
Expand Down
9 changes: 7 additions & 2 deletions src/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,11 @@ export class Version {
* tags "float" (they move with the more specific patch version). The
* `toString` method of this class already accounts for this behavior.
*
* @param manifestPath The path to the manifest file
* @param workspace The project workspace
* @param allowPrerelease True to allow prerelease version conflicts
* @returns True if the version tags exist, otherwise false
*/
async exists(workspace: string): Promise<boolean> {
async exists(workspace: string, allowPrerelease: boolean): Promise<boolean> {
core.info(`Checking for tag: ${this.toString(true)}`)

const tagOptions: TagOptions = new TagOptions(workspace)
Expand All @@ -292,6 +292,11 @@ export class Version {
core.debug(`STDOUT: ${tagOptions.stdout}`)
core.debug(`STDERR: ${tagOptions.stderr}`)

if (this.prerelease && allowPrerelease) {
core.info('Prerelease version conflict allowed')
return false
}

if (tagOptions.stdout.includes(this.toString(true))) return true
else return false
}
Expand Down

0 comments on commit fb19df4

Please sign in to comment.