diff --git a/.github/changelog/pre_commit_hook.js b/.github/changelog/pre_commit_hook.js index c2b807c..d07163b 100644 --- a/.github/changelog/pre_commit_hook.js +++ b/.github/changelog/pre_commit_hook.js @@ -24,7 +24,7 @@ async function latestRelease() { async function latestDevRelease() { const buildEntries = await fs.readdir(SWIFT_ORG_BUILD, { withFileTypes: true }); - const devBranchRegex = /swift-(.*)-branch/; + const devBranchRegex = /swift-([^-]*)-branch/; const devDirs = buildEntries.flatMap(entry => { if (!entry.isDirectory() || !devBranchRegex.exec(entry.name)) { return []; diff --git a/__tests__/snapshot/xcode.test.ts b/__tests__/snapshot/xcode.test.ts index 46777c4..115ec44 100644 --- a/__tests__/snapshot/xcode.test.ts +++ b/__tests__/snapshot/xcode.test.ts @@ -114,7 +114,7 @@ describe('fetch macos tool data based on options', () => { function getVersions(folders: string[], suffix: string) { return folders.flatMap(folder => { - const match = folder.match(`swift-([0-9_]+)-${suffix}`) + const match = folder.match(`swift-([^-]*)-${suffix}`) if (match?.length) { return match[1] } diff --git a/dist/index.js b/dist/index.js index 5d7e889..a4e5a2e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -83,12 +83,13 @@ const exec_1 = __nccwpck_require__(1514); const cache = __importStar(__nccwpck_require__(7799)); const toolCache = __importStar(__nccwpck_require__(7784)); const semver_1 = __nccwpck_require__(1383); +const version_1 = __nccwpck_require__(4428); class ToolchainInstaller { constructor(data) { this.data = data; } get version() { - const match = /swift-(.*)-/.exec(this.data.branch); + const match = version_1.SWIFT_BRANCH_REGEX.exec(this.data.branch); return match && match.length > 1 ? (0, semver_1.coerce)(match[1]) : undefined; } get baseUrl() { @@ -863,7 +864,7 @@ function run() { else { throw new Error(`No Swift toolchain found for ${version}`); } - const match = /swift-(.*)-/.exec(toolchain.branch); + const match = version_1.SWIFT_BRANCH_REGEX.exec(toolchain.branch); if (match && match.length > 1) { installedVersion = match[1]; } @@ -930,12 +931,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.Platform = void 0; const path = __importStar(__nccwpck_require__(1017)); const fs_1 = __nccwpck_require__(7147); const core = __importStar(__nccwpck_require__(2186)); const yaml = __importStar(__nccwpck_require__(1917)); +const semver_1 = __importDefault(__nccwpck_require__(1383)); +const version_1 = __nccwpck_require__(4428); const const_1 = __nccwpck_require__(6695); const RELEASE_FILE = path.join(const_1.MODULE_DIR, 'swiftorg', '_data', 'builds', 'swift_releases.yml'); class Platform { @@ -950,12 +956,27 @@ class Platform { return yaml.load(data); }); } + sortSnapshots(snapshots) { + return snapshots.sort((item1, item2) => { + var _a, _b; + const t1 = item1; + const t2 = item2; + const ver1 = semver_1.default.coerce((_a = version_1.SWIFT_BRANCH_REGEX.exec(t1.branch)) === null || _a === void 0 ? void 0 : _a[0]); + const ver2 = semver_1.default.coerce((_b = version_1.SWIFT_BRANCH_REGEX.exec(t2.branch)) === null || _b === void 0 ? void 0 : _b[0]); + if (ver1 && ver2) { + const comparison = semver_1.default.compare(ver2, ver1); + if (comparison !== 0) { + return comparison; + } + } + return t2.date.getTime() - t1.date.getTime(); + }); + } tools(version) { return __awaiter(this, void 0, void 0, function* () { const snapshots = yield this.releasedTools(version); if (snapshots.length && !version.dev) { - return snapshots.sort((item1, item2) => item2.date.getTime() - - item1.date.getTime()); + return this.sortSnapshots(snapshots); } const files = yield this.toolFiles(version); core.debug(`Using files "${files}" to get toolchains snapshot data`); @@ -978,8 +999,7 @@ class Platform { }) .filter(item => version.satisfiedBy(item.dir)); snapshots.push(...devSnapshots); - return snapshots.sort((item1, item2) => item2.date.getTime() - - item1.date.getTime()); + return this.sortSnapshots(snapshots); }); } } @@ -1156,6 +1176,7 @@ exports.LinuxPlatform = void 0; const path = __importStar(__nccwpck_require__(1017)); const fs_1 = __nccwpck_require__(7147); const versioned_1 = __nccwpck_require__(1325); +const version_1 = __nccwpck_require__(4428); const installer_1 = __nccwpck_require__(8979); const const_1 = __nccwpck_require__(6695); class LinuxPlatform extends versioned_1.VersionedPlatform { @@ -1181,7 +1202,7 @@ class LinuxPlatform extends versioned_1.VersionedPlatform { return tool; } let headingPattern; - const match = /swift-(.*)-/.exec(tool.branch); + const match = version_1.SWIFT_BRANCH_REGEX.exec(tool.branch); if (match && match.length > 1) { const ver = match[1]; headingPattern = new RegExp(`Swift ${ver}`, 'g'); @@ -2317,10 +2338,11 @@ exports.LatestToolchainVersion = LatestToolchainVersion; "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.ToolchainSnapshotName = exports.DEVELOPMENT_SNAPSHOT = void 0; +exports.ToolchainSnapshotName = exports.SWIFT_BRANCH_REGEX = exports.DEVELOPMENT_SNAPSHOT = void 0; const semver_1 = __nccwpck_require__(1383); const base_1 = __nccwpck_require__(2120); exports.DEVELOPMENT_SNAPSHOT = 'DEVELOPMENT-SNAPSHOT'; +exports.SWIFT_BRANCH_REGEX = /swift-([^-]*)-.*/; class ToolchainSnapshotName extends base_1.ToolchainVersion { constructor(name) { super(name.includes(exports.DEVELOPMENT_SNAPSHOT)); @@ -2333,7 +2355,7 @@ class ToolchainSnapshotName extends base_1.ToolchainVersion { return `swift-${this.name}`; } get version() { - const match = /swift-([^-]*)-/.exec(this.dir); + const match = exports.SWIFT_BRANCH_REGEX.exec(this.dir); if (!match || match.length < 2 || !(0, semver_1.coerce)(match[1])) { return; } diff --git a/src/installer/base.ts b/src/installer/base.ts index c488214..4374488 100644 --- a/src/installer/base.ts +++ b/src/installer/base.ts @@ -5,6 +5,7 @@ import {getExecOutput} from '@actions/exec' import * as cache from '@actions/cache' import * as toolCache from '@actions/tool-cache' import {coerce as parseSemVer} from 'semver' +import {SWIFT_BRANCH_REGEX} from '../version' import {ToolchainSnapshot} from '../snapshot' export type SnapshotForInstaller = @@ -16,7 +17,7 @@ export abstract class ToolchainInstaller { constructor(readonly data: Snapshot) {} protected get version() { - const match = /swift-(.*)-/.exec(this.data.branch) + const match = SWIFT_BRANCH_REGEX.exec(this.data.branch) return match && match.length > 1 ? parseSemVer(match[1]) : undefined } diff --git a/src/main.ts b/src/main.ts index 2604f39..9454c3a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ import * as core from '@actions/core' -import {ToolchainVersion} from './version' +import {ToolchainVersion, SWIFT_BRANCH_REGEX} from './version' import {Swiftorg} from './swiftorg' import {ToolchainSnapshot} from './snapshot' import {Platform} from './platform' @@ -26,7 +26,7 @@ export async function run() { } else { throw new Error(`No Swift toolchain found for ${version}`) } - const match = /swift-(.*)-/.exec(toolchain.branch) + const match = SWIFT_BRANCH_REGEX.exec(toolchain.branch) if (match && match.length > 1) { installedVersion = match[1] } else { diff --git a/src/platform/base.ts b/src/platform/base.ts index 620d498..502bb66 100644 --- a/src/platform/base.ts +++ b/src/platform/base.ts @@ -2,7 +2,8 @@ import * as path from 'path' import {promises as fs} from 'fs' import * as core from '@actions/core' import * as yaml from 'js-yaml' -import {ToolchainVersion} from '../version' +import semver from 'semver' +import {ToolchainVersion, SWIFT_BRANCH_REGEX} from '../version' import {ToolchainSnapshot, SwiftRelease} from '../snapshot' import {ToolchainInstaller, SnapshotForInstaller} from '../installer' import {MODULE_DIR} from '../const' @@ -32,6 +33,22 @@ export abstract class Platform< return yaml.load(data) as SwiftRelease[] } + private sortSnapshots(snapshots: SnapshotForInstaller[]) { + return snapshots.sort((item1, item2) => { + const t1 = item1 as ToolchainSnapshot + const t2 = item2 as ToolchainSnapshot + const ver1 = semver.coerce(SWIFT_BRANCH_REGEX.exec(t1.branch)?.[0]) + const ver2 = semver.coerce(SWIFT_BRANCH_REGEX.exec(t2.branch)?.[0]) + if (ver1 && ver2) { + const comparison = semver.compare(ver2, ver1) + if (comparison !== 0) { + return comparison + } + } + return t2.date.getTime() - t1.date.getTime() + }) + } + protected abstract releasedTools( version: ToolchainVersion ): Promise[]> @@ -41,11 +58,7 @@ export abstract class Platform< ): Promise[]> { const snapshots = await this.releasedTools(version) if (snapshots.length && !version.dev) { - return snapshots.sort( - (item1, item2) => - (item2 as ToolchainSnapshot).date.getTime() - - (item1 as ToolchainSnapshot).date.getTime() - ) + return this.sortSnapshots(snapshots) } const files = await this.toolFiles(version) core.debug(`Using files "${files}" to get toolchains snapshot data`) @@ -76,11 +89,7 @@ export abstract class Platform< }) .filter(item => version.satisfiedBy((item as ToolchainSnapshot).dir)) snapshots.push(...devSnapshots) - return snapshots.sort( - (item1, item2) => - (item2 as ToolchainSnapshot).date.getTime() - - (item1 as ToolchainSnapshot).date.getTime() - ) + return this.sortSnapshots(snapshots) } abstract install( diff --git a/src/platform/linux.ts b/src/platform/linux.ts index 9f60cca..0ea5c18 100644 --- a/src/platform/linux.ts +++ b/src/platform/linux.ts @@ -1,7 +1,7 @@ import * as path from 'path' import {promises as fs} from 'fs' import {VersionedPlatform} from './versioned' -import {ToolchainVersion} from '../version' +import {ToolchainVersion, SWIFT_BRANCH_REGEX} from '../version' import {LinuxToolchainSnapshot} from '../snapshot' import {LinuxToolchainInstaller} from '../installer' import {MODULE_DIR} from '../const' @@ -26,7 +26,7 @@ export class LinuxPlatform extends VersionedPlatform { return tool } let headingPattern: RegExp - const match = /swift-(.*)-/.exec(tool.branch) + const match = SWIFT_BRANCH_REGEX.exec(tool.branch) if (match && match.length > 1) { const ver = match[1] headingPattern = new RegExp(`Swift ${ver}`, 'g') diff --git a/src/version/name.ts b/src/version/name.ts index 264433b..dad573b 100644 --- a/src/version/name.ts +++ b/src/version/name.ts @@ -2,6 +2,7 @@ import {coerce as parseSemVer} from 'semver' import {ToolchainVersion} from './base' export const DEVELOPMENT_SNAPSHOT = 'DEVELOPMENT-SNAPSHOT' +export const SWIFT_BRANCH_REGEX = /swift-([^-]*)-.*/ export class ToolchainSnapshotName extends ToolchainVersion { constructor(readonly name: string) { @@ -16,7 +17,7 @@ export class ToolchainSnapshotName extends ToolchainVersion { } private get version() { - const match = /swift-([^-]*)-/.exec(this.dir) + const match = SWIFT_BRANCH_REGEX.exec(this.dir) if (!match || match.length < 2 || !parseSemVer(match[1])) { return }