diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md
index d2151ce01..464534ba9 100644
--- a/DOCUMENTATION.md
+++ b/DOCUMENTATION.md
@@ -367,7 +367,7 @@ const sdk = fromSharedOptions();
* [.download(options)](#balena.models.os.download) ⇒ Promise
* [.getConfig(slugOrUuidOrId, options)](#balena.models.os.getConfig) ⇒ Promise
* [.isSupportedOsUpdate(deviceType, currentVersion, targetVersion)](#balena.models.os.isSupportedOsUpdate) ⇒ Promise
- * [.getSupportedOsUpdateVersions(deviceType, currentVersion)](#balena.models.os.getSupportedOsUpdateVersions) ⇒ Promise
+ * [.getSupportedOsUpdateVersions(deviceType, currentVersion, [options])](#balena.models.os.getSupportedOsUpdateVersions) ⇒ Promise
* [.isArchitectureCompatibleWith(osArchitecture, applicationArchitecture)](#balena.models.os.isArchitectureCompatibleWith) ⇒ Boolean
* [.getSupervisorImageForDeviceType(deviceTypeId, version)](#balena.models.os.getSupervisorImageForDeviceType) ⇒ Promise.<String>
* [.config](#balena.models.config) : object
@@ -774,7 +774,7 @@ balena.models.device.get(123).catch(function (error) {
* [.download(options)](#balena.models.os.download) ⇒ Promise
* [.getConfig(slugOrUuidOrId, options)](#balena.models.os.getConfig) ⇒ Promise
* [.isSupportedOsUpdate(deviceType, currentVersion, targetVersion)](#balena.models.os.isSupportedOsUpdate) ⇒ Promise
- * [.getSupportedOsUpdateVersions(deviceType, currentVersion)](#balena.models.os.getSupportedOsUpdateVersions) ⇒ Promise
+ * [.getSupportedOsUpdateVersions(deviceType, currentVersion, [options])](#balena.models.os.getSupportedOsUpdateVersions) ⇒ Promise
* [.isArchitectureCompatibleWith(osArchitecture, applicationArchitecture)](#balena.models.os.isArchitectureCompatibleWith) ⇒ Boolean
* [.getSupervisorImageForDeviceType(deviceTypeId, version)](#balena.models.os.getSupervisorImageForDeviceType) ⇒ Promise.<String>
* [.config](#balena.models.config) : object
@@ -5261,7 +5261,7 @@ balena.models.organization.remove(123);
* [.download(options)](#balena.models.os.download) ⇒ Promise
* [.getConfig(slugOrUuidOrId, options)](#balena.models.os.getConfig) ⇒ Promise
* [.isSupportedOsUpdate(deviceType, currentVersion, targetVersion)](#balena.models.os.isSupportedOsUpdate) ⇒ Promise
- * [.getSupportedOsUpdateVersions(deviceType, currentVersion)](#balena.models.os.getSupportedOsUpdateVersions) ⇒ Promise
+ * [.getSupportedOsUpdateVersions(deviceType, currentVersion, [options])](#balena.models.os.getSupportedOsUpdateVersions) ⇒ Promise
* [.isArchitectureCompatibleWith(osArchitecture, applicationArchitecture)](#balena.models.os.isArchitectureCompatibleWith) ⇒ Boolean
* [.getSupervisorImageForDeviceType(deviceTypeId, version)](#balena.models.os.getSupervisorImageForDeviceType) ⇒ Promise.<String>
@@ -5468,10 +5468,12 @@ balena.models.os.isSupportedOsUpgrade('raspberry-pi', '2.9.6+rev2.prod', '2.29.2
```
-##### os.getSupportedOsUpdateVersions(deviceType, currentVersion) ⇒ Promise
+##### os.getSupportedOsUpdateVersions(deviceType, currentVersion, [options]) ⇒ Promise
**Kind**: static method of [os
](#balena.models.os)
**Summary**: Returns the supported OS update targets for the provided device type
**Access**: public
+**Fulfil**: Object[]\|Object
- An array of OsVersion objects when a single device type slug is provided,
+or a dictionary of OsVersion objects by device type slug when an array of device type slugs is provided.
**Fulfil**: Object
- the versions information, of the following structure:
* versions - an array of strings,
containing exact version numbers that OS update is supported
@@ -5479,10 +5481,12 @@ containing exact version numbers that OS update is supported
that is _not_ pre-release, can be `null`
* current - the provided current version after normalization
-| Param | Type | Description |
-| --- | --- | --- |
-| deviceType | String
| device type slug |
-| currentVersion | String
| semver-compatible version for the starting OS version |
+| Param | Type | Default | Description |
+| --- | --- | --- | --- |
+| deviceType | String
| | device type slug |
+| currentVersion | String
| | semver-compatible version for the starting OS version |
+| [options] | Object
| | Extra options to filter the OS releases by |
+| [options.includeDraft] | Boolean
| false
| Whether pre-releases should be included in the results |
**Example**
```js
diff --git a/src/models/os.ts b/src/models/os.ts
index ea2f1c1cd..8647d4630 100644
--- a/src/models/os.ts
+++ b/src/models/os.ts
@@ -877,6 +877,10 @@ const getOsModel = function (
*
* @param {String} deviceType - device type slug
* @param {String} currentVersion - semver-compatible version for the starting OS version
+ * @param {Object} [options] - Extra options to filter the OS releases by
+ * @param {Boolean} [options.includeDraft=false] - Whether pre-releases should be included in the results
+ * @fulfil {Object[]|Object} - An array of OsVersion objects when a single device type slug is provided,
+ * or a dictionary of OsVersion objects by device type slug when an array of device type slugs is provided.
* @fulfil {Object} - the versions information, of the following structure:
* * versions - an array of strings,
* containing exact version numbers that OS update is supported
@@ -893,9 +897,10 @@ const getOsModel = function (
const getSupportedOsUpdateVersions = async (
deviceType: string,
currentVersion: string,
+ options?: { includeDraft?: boolean },
): Promise => {
deviceType = await _getNormalizedDeviceTypeSlug(deviceType);
- const allVersions = (await getAvailableOsVersions(deviceType))
+ const allVersions = (await getAvailableOsVersions(deviceType, options))
.filter((v) => v.osType === OsTypes.DEFAULT)
.map((v) => v.raw_version);
// use bSemver.compare to find the current version in the OS list
diff --git a/tests/integration/models/os.spec.ts b/tests/integration/models/os.spec.ts
index db49107a0..ed4069639 100644
--- a/tests/integration/models/os.spec.ts
+++ b/tests/integration/models/os.spec.ts
@@ -860,24 +860,64 @@ describe('OS model', function () {
);
}));
- describe('given a valid device slug', () =>
- it('should return the list of supported hup targets', () =>
- balena.models.os
- .getSupportedOsUpdateVersions('raspberrypi3', '2.9.6+rev1.prod')
- .then(function ({ current, recommended, versions }) {
- expect(current).to.equal('2.9.6+rev1.prod');
- expect(recommended).to.be.a('string');
- expect(versions).to.be.an('array');
- expect(versions).to.not.have.length(0);
- versions.forEach(function (v) {
- expect(v).to.be.a('string');
- expect(bSemver.gte(v, current)).to.be.true;
- });
+ describe('given a valid device slug', () => {
+ it('should return the list of supported hup targets', async () => {
+ const { current, recommended, versions } =
+ await balena.models.os.getSupportedOsUpdateVersions(
+ 'raspberrypi3',
+ '2.9.6+rev1.prod',
+ );
+ expect(current).to.equal('2.9.6+rev1.prod');
+ expect(recommended).to.be.a('string');
+ expect(versions).to.be.an('array');
+ expect(versions).to.not.have.length(0);
+ versions.forEach(function (v) {
+ expect(v).to.be.a('string');
+ expect(bSemver.gte(v, current)).to.be.true;
+ });
+
+ expect(versions.length > 2).to.be.true;
+ const sortedVersions = versions.slice().sort(bSemver.rcompare);
+ expect(versions).to.deep.equal(sortedVersions);
+ });
+
+ it('should not include draft OS releases when the respective flag is not used', async () => {
+ const { current, recommended, versions } =
+ await balena.models.os.getSupportedOsUpdateVersions(
+ 'raspberrypi3',
+ '2.9.6+rev1.prod',
+ );
+ expect(current).to.equal('2.9.6+rev1.prod');
+ expect(recommended).to.be.a('string');
+ expect(versions).to.be.an('array');
+ expect(versions).to.not.have.length(0);
+
+ const draftVersions = versions.filter(
+ (v) => bSemver.parse(v)?.prerelease.length ?? 0 > 0,
+ );
+ expect(draftVersions).to.have.lengthOf(0);
+ });
+
+ // This relies on the API we are testing against having a newer OS version
+ // that's a draft, like api.balena-cloud.com had at the time of writing this test.
+ it('should include draft OS releases when the respective flag is used', async () => {
+ const { current, recommended, versions } =
+ await balena.models.os.getSupportedOsUpdateVersions(
+ 'raspberrypi3',
+ '2.9.6+rev1.prod',
+ { includeDraft: true },
+ );
+ expect(current).to.equal('2.9.6+rev1.prod');
+ expect(recommended).to.be.a('string');
+ expect(versions).to.be.an('array');
+ expect(versions).to.not.have.length(0);
- expect(versions.length > 2).to.be.true;
- const sortedVersions = versions.slice().sort(bSemver.rcompare);
- expect(versions).to.deep.equal(sortedVersions);
- })));
+ const draftVersions = versions.filter(
+ (v) => bSemver.parse(v)?.prerelease.length ?? 0 > 0,
+ );
+ expect(draftVersions).to.have.length.greaterThan(0);
+ });
+ });
});
describe('when logged in as a user with a single application', function () {