Fetch SD versions through 'gh release list -R libsdl-org/SDL -L 1000'
diff --git a/packed/index.js b/packed/index.js
index 617f50d..734d5ae 100644
--- a/packed/index.js
+++ b/packed/index.js
@@ -7,47 +7,9 @@
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.SDL_TAGS = exports.SDL_GIT_URL = exports.NINJA_VERSION = void 0;
+exports.SDL_GIT_URL = exports.NINJA_VERSION = void 0;
 exports.NINJA_VERSION = "1.11.1";
 exports.SDL_GIT_URL = "https://github.com/libsdl-org/SDL.git";
-exports.SDL_TAGS = [
-    "2.0.22-RC1",
-    "2.0.22-RC2",
-    "2.0.22-RC3",
-    "release-2.0.0",
-    "release-2.0.1",
-    "release-2.0.2",
-    "release-2.0.3",
-    "release-2.0.4",
-    "release-2.0.5",
-    "release-2.0.6",
-    "release-2.0.7",
-    "release-2.0.8",
-    "release-2.0.9",
-    "release-2.0.10",
-    "release-2.0.12",
-    "release-2.0.14",
-    "release-2.0.16",
-    "release-2.0.18",
-    "release-2.0.20",
-    "release-2.0.22",
-    "prerelease-2.23.1",
-    "prerelease-2.23.2",
-    "release-2.24.0",
-    "release-2.24.1",
-    "release-2.24.2",
-    "prerelease-2.25.1",
-    "release-2.26.0",
-    "release-2.26.1",
-    "release-2.26.2",
-    "release-2.26.3",
-    "release-2.26.4",
-    "release-2.26.5",
-    "prerelease-2.27.1",
-    // Add SDL2 releases here
-    "prerelease-3.0.0",
-    // Add SDL3 releases here
-];
 
 
 /***/ }),
@@ -385,7 +347,7 @@
 }
 function run() {
     return __awaiter(this, void 0, void 0, function () {
-        var SDL_BUILD_PLATFORM, SETUP_SDL_ROOT, IGNORED_SHELLS, shell_in, SHELL, REQUESTED_VERSION_TYPE, CMAKE_BUILD_TYPE, CMAKE_BUILD_TYPES, git_branch_hash, requested_version, requested_type, sdl_release, GIT_HASH, CMAKE_TOOLCHAIN_FILE, STATE_HASH, PACKAGE_DIR, CACHE_KEY, CACHE_PATHS, sdl_from_cache, SOURCE_DIR, BUILD_DIR, USE_NINJA, cmake_configure_args, SDL_VERSION;
+        var SDL_BUILD_PLATFORM, SETUP_SDL_ROOT, IGNORED_SHELLS, shell_in, SHELL, REQUESTED_VERSION_TYPE, CMAKE_BUILD_TYPE, CMAKE_BUILD_TYPES, git_branch_hash, requested_version, requested_type, github_releases, release_db, sdl_release, GIT_HASH, CMAKE_TOOLCHAIN_FILE, STATE_HASH, PACKAGE_DIR, CACHE_KEY, CACHE_PATHS, sdl_from_cache, SOURCE_DIR, BUILD_DIR, USE_NINJA, cmake_configure_args, SDL_VERSION;
         var _this = this;
         return __generator(this, function (_a) {
             switch (_a.label) {
@@ -428,7 +390,9 @@
                             }
                         }
                         else {
-                            sdl_release = version_1.SdlRelease.find_release(requested_version, core.getBooleanInput("pre-release"), requested_type);
+                            github_releases = version_1.GitHubRelease.fetch_all("libsdl-org/SDL");
+                            release_db = version_1.SdlReleaseDb.create(github_releases);
+                            sdl_release = release_db.find(requested_version, core.getBooleanInput("pre-release"), requested_type);
                             if (!sdl_release) {
                                 throw new util_1.SetupSdlError("Could not find a matching SDL release for ".concat(requested_version));
                             }
@@ -845,10 +809,30 @@
     return result;
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.parse_requested_sdl_version = exports.SdlRelease = exports.SdlReleaseType = exports.SdlVersion = void 0;
+exports.parse_requested_sdl_version = exports.SdlRelease = exports.SdlReleaseDb = exports.SdlReleaseType = exports.SdlVersion = exports.GitHubRelease = void 0;
+var child_process = __importStar(__nccwpck_require__(2081));
 var fs = __importStar(__nccwpck_require__(7147));
-var constants_1 = __nccwpck_require__(7077);
 var util_1 = __nccwpck_require__(9731);
+var GitHubRelease = /** @class */ (function () {
+    function GitHubRelease(name, prerelease, tag, time) {
+        this.name = name;
+        this.prerelease = prerelease;
+        this.tag = tag;
+        this.time = time;
+    }
+    GitHubRelease.fetch_all = function (repo) {
+        var buffer = child_process.execSync("gh release list -R ".concat(repo, " -L 1000"));
+        return GitHubRelease.from_gh_output(buffer.toString());
+    };
+    GitHubRelease.from_gh_output = function (text) {
+        return text.trim().split("\n").map(function (line_str) {
+            var line_parts = line_str.split("\t");
+            return new GitHubRelease(line_parts[0], line_parts[1].toLowerCase() == "pre-release", line_parts[2], Date.parse(line_parts[3]));
+        });
+    };
+    return GitHubRelease;
+}());
+exports.GitHubRelease = GitHubRelease;
 var SdlVersion = /** @class */ (function () {
     function SdlVersion(version) {
         if (typeof version == "string") {
@@ -961,20 +945,36 @@
     SdlReleaseType["Latest"] = "Latest";
     SdlReleaseType["Exact"] = "Exact";
 })(SdlReleaseType = exports.SdlReleaseType || (exports.SdlReleaseType = {}));
-var SdlRelease = /** @class */ (function () {
-    function SdlRelease(version, prerelease, tag) {
-        this.version = version;
-        this.prerelease = prerelease;
-        this.tag = tag;
+var SdlReleaseDb = /** @class */ (function () {
+    function SdlReleaseDb(releases) {
+        this.releases = releases;
     }
-    SdlRelease.get_releases = function () {
-        var releases = [];
+    SdlReleaseDb.prototype.find = function (version, prerelease, type) {
+        for (var _i = 0, _a = this.releases; _i < _a.length; _i++) {
+            var release = _a[_i];
+            // Skip if a pre-release has not been requested
+            if (release.prerelease != null && !prerelease) {
+                continue;
+            }
+            if (type == SdlReleaseType.Exact) {
+                if (release.version.equals(version)) {
+                    return release;
+                }
+            }
+            if (type == SdlReleaseType.Latest || type == SdlReleaseType.Any) {
+                if (release.version.major == version.major) {
+                    return release;
+                }
+            }
+        }
+        return null;
+    };
+    SdlReleaseDb.create = function (github_releases) {
         var R = new RegExp("(release-|prerelease-)?([0-9.]+)(-RC([0-9]+))?");
-        for (var _i = 0, SDL_TAGS_1 = constants_1.SDL_TAGS; _i < SDL_TAGS_1.length; _i++) {
-            var tag = SDL_TAGS_1[_i];
-            var m = tag.match(R);
+        var releases = github_releases.map(function (gh_release) {
+            var m = gh_release.tag.match(R);
             if (m == null) {
-                throw new util_1.SetupSdlError("Invalid tag: ".concat(tag));
+                throw new util_1.SetupSdlError("Invalid tag: ".concat(gh_release.tag));
             }
             var prerelease = null;
             if (m[1] != null && m[1] != "release-") {
@@ -984,34 +984,22 @@
                 prerelease = Number(m[4]) + 1;
             }
             var version = m[2];
-            releases.push(new SdlRelease(new SdlVersion(version), prerelease, tag));
-        }
+            return new SdlRelease(new SdlVersion(version), prerelease, gh_release.tag);
+        });
         releases.sort(function (release1, release2) {
             return release1.compare(release2);
         });
-        return releases;
+        return new SdlReleaseDb(releases);
     };
-    SdlRelease.find_release = function (version, prerelease, type) {
-        var RELEASES = SdlRelease.get_releases();
-        for (var _i = 0, RELEASES_1 = RELEASES; _i < RELEASES_1.length; _i++) {
-            var sdl_release = RELEASES_1[_i];
-            // Skip if a pre-release has not been requested
-            if (sdl_release.prerelease != null && !prerelease) {
-                continue;
-            }
-            if (type == SdlReleaseType.Exact) {
-                if (sdl_release.version.equals(version)) {
-                    return sdl_release;
-                }
-            }
-            if (type == SdlReleaseType.Latest || type == SdlReleaseType.Any) {
-                if (sdl_release.version.major == version.major) {
-                    return sdl_release;
-                }
-            }
-        }
-        return null;
-    };
+    return SdlReleaseDb;
+}());
+exports.SdlReleaseDb = SdlReleaseDb;
+var SdlRelease = /** @class */ (function () {
+    function SdlRelease(version, prerelease, tag) {
+        this.version = version;
+        this.prerelease = prerelease;
+        this.tag = tag;
+    }
     SdlRelease.prototype.compare = function (other) {
         var cmp = this.version.compare(other.version);
         if (cmp != 0) {
diff --git a/src/constants.ts b/src/constants.ts
index cfa7da9..7c1ba19 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -1,42 +1,3 @@
 export const NINJA_VERSION = "1.11.1";
 
 export const SDL_GIT_URL = "https://github.com/libsdl-org/SDL.git";
-
-export const SDL_TAGS = [
-  "2.0.22-RC1",
-  "2.0.22-RC2",
-  "2.0.22-RC3",
-  "release-2.0.0",
-  "release-2.0.1",
-  "release-2.0.2",
-  "release-2.0.3",
-  "release-2.0.4",
-  "release-2.0.5",
-  "release-2.0.6",
-  "release-2.0.7",
-  "release-2.0.8",
-  "release-2.0.9",
-  "release-2.0.10",
-  "release-2.0.12",
-  "release-2.0.14",
-  "release-2.0.16",
-  "release-2.0.18",
-  "release-2.0.20",
-  "release-2.0.22",
-  "prerelease-2.23.1",
-  "prerelease-2.23.2",
-  "release-2.24.0",
-  "release-2.24.1",
-  "release-2.24.2",
-  "prerelease-2.25.1",
-  "release-2.26.0",
-  "release-2.26.1",
-  "release-2.26.2",
-  "release-2.26.3",
-  "release-2.26.4",
-  "release-2.26.5",
-  "prerelease-2.27.1",
-  // Add SDL2 releases here
-  "prerelease-3.0.0",
-  // Add SDL3 releases here
-];
diff --git a/src/main.ts b/src/main.ts
index a13349d..89f2805 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -12,7 +12,8 @@
 import { SetupSdlError } from "./util";
 
 import {
-  SdlRelease,
+  GitHubRelease,
+  SdlReleaseDb,
   SdlReleaseType,
   SdlVersion,
   parse_requested_sdl_version,
@@ -306,7 +307,9 @@
         throw new SetupSdlError("Invalid -head version");
       }
     } else {
-      const sdl_release = SdlRelease.find_release(
+      const github_releases = GitHubRelease.fetch_all("libsdl-org/SDL");
+      const release_db = SdlReleaseDb.create(github_releases);
+      const sdl_release = release_db.find(
         requested_version,
         core.getBooleanInput("pre-release"),
         requested_type
diff --git a/src/version.test.ts b/src/version.test.ts
index 9a55536..a2e677e 100644
--- a/src/version.test.ts
+++ b/src/version.test.ts
@@ -1,12 +1,39 @@
 import {
+  GitHubRelease,
   parse_requested_sdl_version,
   SdlVersion,
   SdlRelease,
+  SdlReleaseDb,
   SdlReleaseType,
 } from "./version";
 
 import { describe, expect, test } from "@jest/globals";
 
+const GH_RELEASE_OUTPUT = ""
+  + "3.1.1\tLatest\tprerelease-3.1.1\t2023-12-25T18:45:17Z\n"
+  + "2.28.0\tLatest\trelease-2.28.0\t2023-06-20T18:45:17Z\n"
+  + "2.28.0 RC1\tPre-release\tprerelease-2.27.1\t2023-06-14T03:59:14Z\n"
+  + "2.26.5\t\trelease-2.26.5\t2023-04-05T19:35:40Z\n"
+  + "2.26.4\t\trelease-2.26.4\t2023-03-07T00:17:02Z\n"
+  + "2.26.3\t\trelease-2.26.3\t2023-02-06T23:31:56Z\n"
+  + "2.26.2\t\trelease-2.26.2\t2023-01-03T15:08:11Z\n"
+  + "2.26.1\t\trelease-2.26.1\t2022-12-01T20:33:11Z\n"
+  + "2.26.0\t\trelease-2.26.0\t2022-11-22T00:28:26Z\n"
+  + "2.26.0 RC1\tPre-release\tprerelease-2.25.1\t2022-11-17T17:49:02Z\n"
+  + "2.24.2\t\trelease-2.24.2\t2022-11-01T13:39:15Z\n"
+  + "2.24.1\t\trelease-2.24.1\t2022-10-05T00:16:33Z\n"
+  + "2.24.0\t\trelease-2.24.0\t2022-08-19T16:04:03Z\n"
+  + "2.0.22\t\trelease-2.0.22\t2022-04-25T19:20:25Z\n"
+  + "2.0.20\t\trelease-2.0.20\t2022-01-11T01:03:58Z\n"
+  + "2.0.18\t\trelease-2.0.18\t2021-11-30T17:15:42Z\n"
+  + "2.0.16\t\trelease-2.0.16\t2021-08-10T16:03:15Z\n"
+  + "2.0.14\t\trelease-2.0.14\t2021-07-08T17:14:16Z\n"
+  + "2.0.12\t\trelease-2.0.12\t2022-05-24T22:37:24Z\n"
+  + "2.0.10\t\trelease-2.0.10\t2022-05-24T22:35:08Z\n"
+  + "2.0.9\t\trelease-2.0.9\t2022-05-24T22:33:03Z\n"
+  + "2.0.8\t\trelease-2.0.8\t2022-05-23T22:20:21Z\n"
+;
+
 describe("testing parsing of version string", () => {
   function add_parse_to_version_test(
     input: string,
@@ -69,11 +96,13 @@
 });
 
 describe("test finding a release", () => {
-  expect(SdlRelease.get_releases()).toBeTruthy();
+  const github_releases = GitHubRelease.from_gh_output(GH_RELEASE_OUTPUT);
+  const sdl_release_db = SdlReleaseDb.create(github_releases);
+  expect(sdl_release_db.releases).toBeTruthy();
 
   test(`test finding exact 2.0.22 release`, () => {
     const v = new SdlVersion({ major: 2, minor: 0, patch: 22 });
-    const rel = SdlRelease.find_release(v, true, SdlReleaseType.Exact);
+    const rel = sdl_release_db.find(v, true, SdlReleaseType.Exact);
     expect(rel).not.toBeNull();
     if (rel) {
       expect(rel.version).toStrictEqual(v);
@@ -83,7 +112,7 @@
 
   test(`test finding exact 2.26.1 release`, () => {
     const v = new SdlVersion({ major: 2, minor: 26, patch: 1 });
-    const rel = SdlRelease.find_release(v, true, SdlReleaseType.Exact);
+    const rel = sdl_release_db.find(v, true, SdlReleaseType.Exact);
     expect(rel).not.toBeNull();
     if (rel) {
       expect(rel.version).toStrictEqual(v);
@@ -93,7 +122,7 @@
 
   test(`test finding latest 2 release`, () => {
     const v = new SdlVersion({ major: 2, minor: 0, patch: 0 });
-    const rel = SdlRelease.find_release(v, true, SdlReleaseType.Latest);
+    const rel = sdl_release_db.find(v, true, SdlReleaseType.Latest);
     expect(rel).not.toBeNull();
     if (rel) {
       // 2.26.5 exists, so the result must be > 2.26.4
@@ -104,7 +133,7 @@
 
   test(`test finding latest non-prerelease 2 release`, () => {
     const v = new SdlVersion({ major: 2, minor: 0, patch: 0 });
-    const rel = SdlRelease.find_release(v, false, SdlReleaseType.Latest);
+    const rel = sdl_release_db.find(v, false, SdlReleaseType.Latest);
     expect(rel).not.toBeNull();
     if (rel) {
       // 2.26.5 exists, so the result must be > 2.26.4
@@ -116,7 +145,7 @@
 
   test(`test finding any 2 release`, () => {
     const v = new SdlVersion({ major: 2, minor: 0, patch: 0 });
-    const rel = SdlRelease.find_release(v, true, SdlReleaseType.Any);
+    const rel = sdl_release_db.find(v, true, SdlReleaseType.Any);
     expect(rel).not.toBeNull();
     if (rel) {
       // 2.26.5 exists, so the result must be > 2.26.4
@@ -126,7 +155,7 @@
 
   test(`test finding any 3 release`, () => {
     const v = new SdlVersion({ major: 3, minor: 0, patch: 0 });
-    const rel = SdlRelease.find_release(v, true, SdlReleaseType.Any);
+    const rel = sdl_release_db.find(v, true, SdlReleaseType.Any);
     expect(rel).not.toBeNull();
     if (rel) {
       // FIXME: Only 3.0.0-prerelease exists at the moment
diff --git a/src/version.ts b/src/version.ts
index c0543c0..eb64351 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1,8 +1,38 @@
+import * as child_process from "child_process";
 import * as fs from "fs";
 
-import { SDL_TAGS } from "./constants";
 import { SetupSdlError } from "./util";
 
+export class GitHubRelease {
+  name: string;
+  prerelease: boolean;
+  tag: string;
+  time: number;
+  constructor(name: string, prerelease: boolean, tag: string, time: number) {
+    this.name = name;
+    this.prerelease = prerelease;
+    this.tag = tag;
+    this.time = time;
+  }
+
+  static fetch_all(repo: string): GitHubRelease[] {
+    const buffer = child_process.execSync(`gh release list -R ${repo} -L 1000`);
+    return GitHubRelease.from_gh_output(buffer.toString());
+  }
+
+  static from_gh_output(text: string): GitHubRelease[] {
+    return text.trim().split("\n").map(line_str => {
+      const line_parts = line_str.split("\t");
+      return new GitHubRelease(
+        line_parts[0],
+        line_parts[1].toLowerCase() == "pre-release",
+        line_parts[2],
+        Date.parse(line_parts[3]),
+      );
+    });
+  }
+}
+
 export class SdlVersion {
   major: number;
   minor: number;
@@ -163,6 +193,62 @@
   Exact = "Exact",
 }
 
+export class SdlReleaseDb {
+  releases: SdlRelease[];
+
+  constructor(releases: SdlRelease[]) {
+    this.releases = releases;
+  }
+
+  find(
+    version: SdlVersion,
+    prerelease: boolean,
+    type: SdlReleaseType
+  ): SdlRelease | null {
+    for (const release of this.releases) {
+      // Skip if a pre-release has not been requested
+      if (release.prerelease != null && !prerelease) {
+        continue;
+      }
+      if (type == SdlReleaseType.Exact) {
+        if (release.version.equals(version)) {
+          return release;
+        }
+      }
+      if (type == SdlReleaseType.Latest || type == SdlReleaseType.Any) {
+        if (release.version.major == version.major) {
+          return release;
+        }
+      }
+    }
+    return null;
+  }
+
+  static create(github_releases: GitHubRelease[]): SdlReleaseDb {
+
+    const R = new RegExp("(release-|prerelease-)?([0-9.]+)(-RC([0-9]+))?");
+    const releases = github_releases.map(gh_release => {
+      const m = gh_release.tag.match(R);
+      if (m == null) {
+        throw new SetupSdlError(`Invalid tag: ${gh_release.tag}`);
+      }
+      let prerelease: number | null = null;
+      if (m[1] != null && m[1] != "release-") {
+        prerelease = 1;
+      } else if (m[3] != null && m[4] != null) {
+        prerelease = Number(m[4]) + 1;
+      }
+      const version = m[2];
+      return new SdlRelease(new SdlVersion(version), prerelease, gh_release.tag);
+    });
+    releases.sort((release1, release2) => {
+      return release1.compare(release2);
+    });
+
+    return new SdlReleaseDb(releases);
+  }
+}
+
 export class SdlRelease {
   version: SdlVersion;
   prerelease: number | null;
@@ -174,55 +260,6 @@
     this.tag = tag;
   }
 
-  static get_releases(): SdlRelease[] {
-    const releases: SdlRelease[] = [];
-    const R = new RegExp("(release-|prerelease-)?([0-9.]+)(-RC([0-9]+))?");
-
-    for (const tag of SDL_TAGS) {
-      const m = tag.match(R);
-      if (m == null) {
-        throw new SetupSdlError(`Invalid tag: ${tag}`);
-      }
-      let prerelease: number | null = null;
-      if (m[1] != null && m[1] != "release-") {
-        prerelease = 1;
-      } else if (m[3] != null && m[4] != null) {
-        prerelease = Number(m[4]) + 1;
-      }
-      const version = m[2];
-      releases.push(new SdlRelease(new SdlVersion(version), prerelease, tag));
-    }
-    releases.sort(function (release1, release2) {
-      return release1.compare(release2);
-    });
-    return releases;
-  }
-
-  static find_release(
-    version: SdlVersion,
-    prerelease: boolean,
-    type: SdlReleaseType
-  ): SdlRelease | null {
-    const RELEASES: SdlRelease[] = SdlRelease.get_releases();
-    for (const sdl_release of RELEASES) {
-      // Skip if a pre-release has not been requested
-      if (sdl_release.prerelease != null && !prerelease) {
-        continue;
-      }
-      if (type == SdlReleaseType.Exact) {
-        if (sdl_release.version.equals(version)) {
-          return sdl_release;
-        }
-      }
-      if (type == SdlReleaseType.Latest || type == SdlReleaseType.Any) {
-        if (sdl_release.version.major == version.major) {
-          return sdl_release;
-        }
-      }
-    }
-    return null;
-  }
-
   compare(other: SdlRelease): number {
     const cmp = this.version.compare(other.version);
     if (cmp != 0) {