@@ -155,9 +155,9 @@ const os = __importStar(__nccwpck_require__(2037));
155155const path = __importStar(__nccwpck_require__(1017));
156156const core = __importStar(__nccwpck_require__(2186));
157157const toolCache = __importStar(__nccwpck_require__(7784));
158- const swift_versions_1  = __nccwpck_require__(8263 );
158+ const fs  = __importStar( __nccwpck_require__(7147) );
159159const gpg_1 = __nccwpck_require__(9060);
160- async function install(version, system) {
160+ async function install(version, system, getPackage ) {
161161    if (os.platform() !== "linux") {
162162        core.error("Trying to run linux installer on non-linux os");
163163        return;
@@ -166,16 +166,17 @@ async function install(version, system) {
166166    if (swiftPath === null || swiftPath.trim().length == 0) {
167167        core.debug(`No matching installation found`);
168168        await (0, gpg_1.setupKeys)();
169-         const swiftPkg = (0, swift_versions_1.swiftPackage)(version, system );
169+         const swiftPkg = await getPackage( );
170170        let { pkg, signature } = await download(swiftPkg);
171171        await (0, gpg_1.verify)(signature, pkg);
172-         swiftPath = await unpack(pkg, swiftPkg.name , version, system);
172+         swiftPath = await unpack(swiftPkg, pkg , version, system);
173173    }
174174    else {
175175        core.debug("Matching installation found");
176176    }
177177    core.debug("Adding swift to path");
178178    let binPath = path.join(swiftPath, "/usr/bin");
179+     core.debug(`Swift binary path (exists=${fs.existsSync(binPath)}: ${binPath}`);
179180    core.addPath(binPath);
180181    core.debug("Swift installed");
181182}
@@ -189,11 +190,16 @@ async function download({ url, name }) {
189190    core.debug("Swift download complete");
190191    return { pkg, signature, name };
191192}
192- async function unpack(packagePath, packageName , version, system) {
193-     core.debug(" Extracting package" );
193+ async function unpack({ name, isStableRelease }, packagePath , version, system) {
194+     core.debug(` Extracting package at ${packagePath}` );
194195    let extractPath = await toolCache.extractTar(packagePath);
195-     core.debug("Package extracted");
196-     let cachedPath = await toolCache.cacheDir(path.join(extractPath, packageName), `swift-${system.name}`, version);
196+     if (isStableRelease) {
197+         extractPath = path.join(extractPath, name);
198+     }
199+     else {
200+         extractPath = path.join(extractPath, `${name}-ubuntu${system.version}`);
201+     }
202+     let cachedPath = await toolCache.cacheDir(path.join(extractPath), `swift-${system.name}`, version);
197203    core.debug("Package cached");
198204    return cachedPath;
199205}
@@ -234,16 +240,15 @@ exports.install = void 0;
234240const core = __importStar(__nccwpck_require__(2186));
235241const toolCache = __importStar(__nccwpck_require__(7784));
236242const path = __importStar(__nccwpck_require__(1017));
237- const swift_versions_1 = __nccwpck_require__(8263);
238243const get_version_1 = __nccwpck_require__(951);
239- async function install(version, system ) {
244+ async function install(version, getPackage ) {
240245    const toolchainName = `swift ${version}`;
241246    const toolchain = await toolchainVersion(toolchainName);
242247    if (toolchain !== version) {
243248        let swiftPath = toolCache.find("swift-macOS", version);
244249        if (swiftPath === null || swiftPath.trim().length == 0) {
245250            core.debug(`No matching installation found`);
246-             const pkg = (0, swift_versions_1.swiftPackage)(version, system );
251+             const pkg = await getPackage( );
247252            const path = await download(pkg);
248253            const extracted = await unpack(pkg, path, version);
249254            swiftPath = extracted;
@@ -272,11 +277,14 @@ async function download({ url }) {
272277    core.debug("Downloading swift for macOS");
273278    return toolCache.downloadTool(url);
274279}
275- async function unpack({ name }, packagePath, version) {
276-     core.debug(" Extracting package" );
280+ async function unpack({ name, isStableRelease  }, packagePath, version) {
281+     core.debug(` Extracting package at ${packagePath}` );
277282    const unpackedPath = await toolCache.extractXar(packagePath);
278-     const extractedPath = await toolCache.extractTar(path.join(unpackedPath, `${name}-package.pkg`, "Payload"));
279-     core.debug("Package extracted");
283+     let tarPath = path.join(unpackedPath, `${name}-package.pkg`, "Payload");
284+     let extractedPath = await toolCache.extractTar(tarPath);
285+     if (!isStableRelease) {
286+         extractedPath = path.join(extractedPath, `${name}-osx`);
287+     }
280288    const cachedPath = await toolCache.cacheDir(extractedPath, "swift-macOS", version);
281289    core.debug("Package cached");
282290    return cachedPath;
@@ -322,27 +330,22 @@ const macos = __importStar(__nccwpck_require__(4713));
322330const linux = __importStar(__nccwpck_require__(7419));
323331const windows = __importStar(__nccwpck_require__(6414));
324332const get_version_1 = __nccwpck_require__(951);
333+ const snapshot_package_1 = __nccwpck_require__(3671);
325334async function run() {
326335    try {
327336        const requestedVersion = core.getInput("swift-version", { required: true });
328337        let platform = await system.getSystem();
329-         let version = versions.verify(requestedVersion, platform);
330-         switch (platform.os) {
331-             case system.OS.MacOS:
332-                 await macos.install(version, platform);
333-                 break;
334-             case system.OS.Ubuntu:
335-                 await linux.install(version, platform);
336-                 break;
337-             case system.OS.Windows:
338-                 await windows.install(version, platform);
339-         }
340-         const current = await (0, get_version_1.getVersion)();
341-         if (current === version) {
342-             core.setOutput("version", version);
338+         try {
339+             let version = versions.verify(requestedVersion, platform);
340+             await install(version, platform, async () => versions.swiftPackage(version, platform));
343341        }
344-         else {
345-             core.error(`Failed to setup requested swift version. requestd: ${version}, actual: ${current}`);
342+         catch {
343+             const resolver = new snapshot_package_1.SnapshotPackageResolver(null);
344+             const pkg = await resolver.execute(requestedVersion, platform);
345+             if (!pkg) {
346+                 throw new Error(`Couldn't form a package for requested version ${requestedVersion} on ${platform}`);
347+             }
348+             await install(pkg.version, platform, async () => pkg);
346349        }
347350    }
348351    catch (error) {
@@ -356,6 +359,25 @@ async function run() {
356359        core.setFailed(`Unexpected error, unable to continue. Please report at https://github.com/swift-actions/setup-swift/issues${os_1.EOL}${dump}`);
357360    }
358361}
362+ async function install(version, platform, getPackage) {
363+     switch (platform.os) {
364+         case system.OS.MacOS:
365+             await macos.install(version, getPackage);
366+             break;
367+         case system.OS.Ubuntu:
368+             await linux.install(version, platform, getPackage);
369+             break;
370+         case system.OS.Windows:
371+             await windows.install(version, platform);
372+     }
373+     const current = await (0, get_version_1.getVersion)();
374+     if (current === version) {
375+         core.setOutput("version", version);
376+     }
377+     else {
378+         core.error(`Failed to setup requested swift version. requestd: ${version}, actual: ${current}`);
379+     }
380+ }
359381run();
360382
361383
@@ -424,6 +446,130 @@ async function getSystem() {
424446exports.getSystem = getSystem;
425447
426448
449+ /***/ }),
450+ 
451+ /***/ 3671:
452+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
453+ 
454+ "use strict";
455+ 
456+ Object.defineProperty(exports, "__esModule", ({ value: true }));
457+ exports.SnapshotPackageResolver = void 0;
458+ const os_1 = __nccwpck_require__(1855);
459+ class SnapshotPackageResolver {
460+     githubToken;
461+     limit = 100;
462+     constructor(githubToken) {
463+         this.githubToken =
464+             githubToken || process.env.API_GITHUB_ACCESS_TOKEN || null;
465+     }
466+     async execute(version, platform) {
467+         const snapshot = await this.getSnapshot(version);
468+         if (!snapshot) {
469+             return null;
470+         }
471+         const pkg = this.getPackage(snapshot, platform);
472+         return pkg;
473+     }
474+     async getSnapshot(version) {
475+         let index = version.indexOf("-");
476+         if (index === -1) {
477+             return null;
478+         }
479+         const branch = version.split("-")[0];
480+         index = version.indexOf("-", index + 1);
481+         if (index === -1) {
482+             const snapshot = await this.fetchSnapshot(branch);
483+             return snapshot;
484+         }
485+         const date = version.slice(index + 1, version.length);
486+         return { branch, date };
487+     }
488+     async fetchSnapshot(targetBranch) {
489+         let page = 0;
490+         while (true) {
491+             const tags = await this.getTags(page);
492+             for (const tag of tags) {
493+                 const snapshot = this.parseSnapshot(tag);
494+                 if (snapshot && snapshot.branch == targetBranch) {
495+                     return snapshot;
496+                 }
497+             }
498+             if (tags.length < this.limit) {
499+                 return null;
500+             }
501+             page += 1;
502+         }
503+     }
504+     parseSnapshot(tag) {
505+         const matches = tag.name.match(/swift(?:-(\d+)\\.(\d+))?-DEVELOPMENT-SNAPSHOT-(\d{4}-\d{2}-\d{2})/);
506+         if (!matches) {
507+             return null;
508+         }
509+         if (matches[1] && matches[2]) {
510+             const major = matches[1];
511+             const minor = matches[2];
512+             return { branch: `${major}.${minor}`, date: matches[3] };
513+         }
514+         return { branch: "main", date: matches[3] };
515+     }
516+     async getTags(page) {
517+         const url = `https://api.github.com/repos/apple/swift/tags?per_page=${this.limit}&page=${page}`;
518+         let headers = {};
519+         if (this.githubToken) {
520+             headers = {
521+                 Authorization: `Bearer ${this.githubToken}`,
522+             };
523+         }
524+         const response = await fetch(url, {
525+             headers: headers,
526+         });
527+         const json = await response.json();
528+         const tags = json.map((e) => {
529+             return { name: e.name };
530+         });
531+         return tags;
532+     }
533+     getPackage(snapshot, system) {
534+         const identifier = snapshot.branch === "main"
535+             ? `swift-DEVELOPMENT-SNAPSHOT-${snapshot.date}-a`
536+             : `swift-${snapshot.branch}-DEVELOPMENT-SNAPSHOT-${snapshot.date}-a`;
537+         let platform;
538+         let archiveFile;
539+         switch (system.os) {
540+             case os_1.OS.MacOS:
541+                 platform = "xcode";
542+                 archiveFile = `${identifier}-osx.pkg`;
543+                 break;
544+             case os_1.OS.Ubuntu:
545+                 platform = `ubuntu${system.version.replace(/\D/g, "")}`;
546+                 archiveFile = `${identifier}-ubuntu${system.version}.tar.gz`;
547+                 break;
548+             default:
549+                 throw new Error("Cannot create download URL for an unsupported platform");
550+         }
551+         let url = "https://swift.org/builds/";
552+         if (snapshot.branch === "main") {
553+             url += "development/";
554+         }
555+         else {
556+             url += `swift-${snapshot.branch}-branch/`;
557+         }
558+         url += `${platform}/`;
559+         url += `${identifier}/`;
560+         url += `${archiveFile}`;
561+         return {
562+             url: url,
563+             name: identifier,
564+             // TODO: Remove hardcodede version for main!
565+             version: snapshot.branch === "main" ? "6.0" : snapshot.branch,
566+             isStableRelease: false,
567+         };
568+     }
569+ }
570+ exports.SnapshotPackageResolver = SnapshotPackageResolver;
571+ 
572+ 
427573/***/ }),
428574
429575/***/ 8263:
@@ -557,6 +703,7 @@ function swiftPackage(version, system) {
557703        url: `https://swift.org/builds/swift-${version}-release/${platform}/swift-${version}-RELEASE/${archiveFile}`,
558704        name: archiveName,
559705        version: version,
706+         isStableRelease: true,
560707    };
561708}
562709exports.swiftPackage = swiftPackage;
0 commit comments