Skip to content

Commit 90eb346

Browse files
authored
Merge pull request #5 from CycloneDX/support-version-ranges
Add support for version ranges
2 parents 9c3e679 + b1f7cdd commit 90eb346

File tree

3 files changed

+33
-11
lines changed

3 files changed

+33
-11
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ GitHub action to generate a CycloneDX SBOM for Go modules.
88

99
### `version`
1010

11-
**Required** The version of cyclonedx-gomod to use.
11+
**Required** The version of cyclonedx-gomod to use. Can be a version range, in which case the latest version matching the range is chosen.
1212

13-
Must either be an [existing semantic version](https://github.com/CycloneDX/cyclonedx-gomod/releases) (e.g. `v0.8.1`, `0.8.1`) or `latest`.
13+
Must either be an [existing semantic version](https://github.com/CycloneDX/cyclonedx-gomod/releases) (e.g. `v0.8.1`, `0.8.1`), [version range](https://github.com/npm/node-semver#ranges) or `latest`.
1414

1515
> ⚠ Only versions `>= v0.8.1` are supported. Specifying versions below that will cause the workflow to fail.
1616
1717
> Using `latest` is generally not recommended and will produce a warning, as it may fail your workflow
1818
> unexpectedly due to breaking changes in newer *cyclonedx-gomod* versions.
19+
> As of v0.3.0, version ranges are supported. Instead of `latest`, consider using `^v0`, `^v0.8` or similar instead.
1920
2021
### `include-stdlib`
2122

@@ -61,15 +62,15 @@ Type of the main component. Default `'application'`.
6162

6263
```yaml
6364
- name: Generate SBOM JSON
64-
uses: CycloneDX/gh-gomod-generate-sbom@main
65+
uses: CycloneDX/gh-gomod-generate-sbom@v0.3.0
6566
with:
6667
json: true
6768
output: bom.json
6869
resolve-licenses: true
69-
version: v0.8.1
70+
version: ^v0
7071

7172
- name: Generate SBOM XML
72-
uses: CycloneDX/gh-gomod-generate-sbom@main
73+
uses: CycloneDX/gh-gomod-generate-sbom@v0.3.0
7374
with:
7475
output: bom.xml
7576
resolve-licenses: true

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ inputs:
4343
default: application
4444
required: false
4545
version:
46-
description: The version of cyclonedx-gomod to use
46+
description: The version of cyclonedx-gomod to use. Can be a version range, in which case the latest version matching the range is chosen
4747
required: true
4848
runs:
4949
using: 'node12'

index.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const input = {
4141
};
4242

4343
const baseDownloadUrl = 'https://github.com/CycloneDX/cyclonedx-gomod/releases/download';
44+
const minimumSupportedVersion = 'v0.8.1';
4445

4546
function buildDownloadUrl(version) {
4647
let fileExtension = "tar.gz";
@@ -64,13 +65,27 @@ async function getLatestReleaseVersion(httpClient) {
6465
const responseJson = await httpClient.getJson('https://api.github.com/repos/CycloneDX/cyclonedx-gomod/releases/latest');
6566
if (responseJson === null) { // HTTP 404
6667
throw new Error('Fetching latest release of cyclonedx-gomod failed: not found');
68+
} else if (responseJson.statusCode !== 200) {
69+
throw new Error(`Unexpected response status: ${responseJson.statusCode}`);
6770
}
6871

69-
if (responseJson.statusCode !== 200) {
72+
const version = responseJson.result.tag_name;
73+
core.info(`Latest version is ${version}`);
74+
return version;
75+
}
76+
77+
async function getReleaseVersionMatchingRange(httpClient, range) {
78+
core.info(`Determining latest release version of cyclonedx-gomod satisfying "${range}"`);
79+
const responseJson = await httpClient.getJson('https://api.github.com/repos/CycloneDX/cyclonedx-gomod/releases');
80+
if (responseJson === null) { // HTTP 404
81+
throw new Error('Fetching latest release of cyclonedx-gomod failed: not found');
82+
} else if (responseJson.statusCode !== 200) {
7083
throw new Error(`Unexpected response status: ${responseJson.statusCode}`);
7184
}
7285

73-
return responseJson.result.tag_name;
86+
const matched = semver.maxSatisfying(responseJson.result.map((release) => release.tag_name), range);
87+
core.info(`Latest release version matching "${range}" is: ${matched}`);
88+
return matched;
7489
}
7590

7691
async function install(version) {
@@ -100,11 +115,17 @@ async function run() {
100115

101116
let versionToInstall = input.version;
102117
if (versionToInstall.toLowerCase() === 'latest') {
103-
core.warning('Using version "latest" is not recommended!');
118+
core.warning('Using version "latest" is not recommended, please use version ranges instead!');
104119
versionToInstall = await getLatestReleaseVersion(httpClient);
105120
} else {
106-
if (semver.lt(versionToInstall, 'v0.8.1')) {
107-
throw new Error('cyclonedx-gomod versions below v0.8.1 are not supported');
121+
if (!semver.validRange(versionToInstall)) {
122+
throw new Error('version must be a valid version range, see https://github.com/npm/node-semver#advanced-range-syntax')
123+
}
124+
125+
versionToInstall = await getReleaseVersionMatchingRange(httpClient, versionToInstall);
126+
127+
if (semver.lt(versionToInstall, minimumSupportedVersion)) {
128+
throw new Error(`cyclonedx-gomod versions below ${minimumSupportedVersion} are not supported`);
108129
}
109130
}
110131

0 commit comments

Comments
 (0)