From 95005dc45262e8082a6941fe9214742832648039 Mon Sep 17 00:00:00 2001 From: Werner Bisschoff Date: Mon, 15 Jun 2026 08:51:29 +0200 Subject: [PATCH 1/2] feat(registry): add hex registry support for elixir, phoenix, and liveview Adds a Hex.pm version fetcher to enable automated version discovery for Elixir ecosystem packages, along with registry definitions for elixir (unversioned, git source), phoenix, and phoenix_live_view (versioned via Hex API). --- packages/registry/src/version-check.ts | 24 ++++++++++++++++++++++++ registry/hex/elixir.yaml | 8 ++++++++ registry/hex/phoenix.yaml | 19 +++++++++++++++++++ registry/hex/phoenix_live_view.yaml | 19 +++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 registry/hex/elixir.yaml create mode 100644 registry/hex/phoenix.yaml create mode 100644 registry/hex/phoenix_live_view.yaml diff --git a/packages/registry/src/version-check.ts b/packages/registry/src/version-check.ts index ce3bf34..7698195 100644 --- a/packages/registry/src/version-check.ts +++ b/packages/registry/src/version-check.ts @@ -32,6 +32,7 @@ const registryFetchers: Record = { npm: fetchNpmVersions, pip: fetchPipVersions, maven: fetchMavenVersions, + hex: fetchHexVersions, }; /** @@ -196,6 +197,29 @@ async function fetchMavenVersions(packageName: string): Promise { })); } +/** + * Fetch versions from Hex.pm API. + * Package names are lowercase with underscores (e.g., "phoenix", "phoenix_live_view"). + */ +async function fetchHexVersions(packageName: string): Promise { + const res = await fetchWithRetry( + `https://hex.pm/api/packages/${encodeURIComponent(packageName)}`, + `Hex`, + packageName, + ); + + const data = (await res.json()) as { + releases?: Array<{ version?: string; inserted_at?: string }>; + }; + + const releases = data.releases ?? []; + + return releases.map((r) => ({ + version: r.version ?? "", + publishedAt: r.inserted_at, + })); +} + /** * Public registries occasionally return 504/503 under load. Retry 5xx and * network errors with exponential backoff; 4xx aborts immediately. diff --git a/registry/hex/elixir.yaml b/registry/hex/elixir.yaml new file mode 100644 index 0000000..d29d664 --- /dev/null +++ b/registry/hex/elixir.yaml @@ -0,0 +1,8 @@ +name: elixir +description: "A dynamic, functional language for building scalable and maintainable applications" +repository: https://github.com/elixir-lang/elixir + +source: + type: git + url: https://github.com/elixir-lang/elixir + docs_path: lib diff --git a/registry/hex/phoenix.yaml b/registry/hex/phoenix.yaml new file mode 100644 index 0000000..e62cb1d --- /dev/null +++ b/registry/hex/phoenix.yaml @@ -0,0 +1,19 @@ +name: phoenix +description: "A productive web framework for building modern web applications in Elixir" +repository: https://github.com/phoenixframework/phoenix + +versions: + - min_version: "1.7.0" + source: + type: git + url: https://github.com/phoenixframework/phoenix + docs_path: guides + tag_pattern: "v{version}" + + - min_version: "1.5.0" + max_version: "1.7.0" + source: + type: git + url: https://github.com/phoenixframework/phoenix + docs_path: guides + tag_pattern: "v{version}" diff --git a/registry/hex/phoenix_live_view.yaml b/registry/hex/phoenix_live_view.yaml new file mode 100644 index 0000000..043e017 --- /dev/null +++ b/registry/hex/phoenix_live_view.yaml @@ -0,0 +1,19 @@ +name: phoenix_live_view +description: "Rich, real-time user experiences with server-rendered HTML in Elixir" +repository: https://github.com/phoenixframework/phoenix_live_view + +versions: + - min_version: "0.20.0" + source: + type: git + url: https://github.com/phoenixframework/phoenix_live_view + docs_path: guides + tag_pattern: "v{version}" + + - min_version: "0.17.0" + max_version: "0.20.0" + source: + type: git + url: https://github.com/phoenixframework/phoenix_live_view + docs_path: guides + tag_pattern: "v{version}" From 115a5523554813dab56e6ddf1326f3f94507cee3 Mon Sep 17 00:00:00 2001 From: Werner Bisschoff Date: Tue, 16 Jun 2026 13:39:02 +0200 Subject: [PATCH 2/2] chore(pr-review): apply feedback from PR #95 Threads processed: - C01: Collapse phoenix.yaml duplicate version entries into one - C02: Collapse phoenix_live_view.yaml duplicate version entries into one - C03: Update elixir.yaml docs_path from 'lib' to 'lib/elixir/pages' - C04: Add fetchHexVersions unit test - C05: Update module comment to include hex --- packages/registry/src/version-check.test.ts | 27 +++++++++++++++++++++ packages/registry/src/version-check.ts | 2 +- registry/hex/elixir.yaml | 2 +- registry/hex/phoenix.yaml | 8 ------ registry/hex/phoenix_live_view.yaml | 8 ------ 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/packages/registry/src/version-check.test.ts b/packages/registry/src/version-check.test.ts index 5ba49e0..0312bd7 100644 --- a/packages/registry/src/version-check.test.ts +++ b/packages/registry/src/version-check.test.ts @@ -137,6 +137,33 @@ describe("discoverVersions", () => { ); }); + it("fetches hex versions and filters to defined ranges", async () => { + const hexDef: VersionedDefinition = { + ...mockDefinition, + name: "phoenix", + registry: "hex", + }; + + const mockFetch = vi.mocked(fetch); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + releases: [ + { version: "1.7.0", inserted_at: "2024-06-01T00:00:00Z" }, + { version: "1.6.0", inserted_at: "2024-03-01T00:00:00Z" }, + { version: "1.5.0", inserted_at: "2024-01-01T00:00:00Z" }, + ], + }), + } as Response); + + const versions = await discoverVersions(hexDef); + + expect(versions.map((v) => v.version)).toEqual(["1.7.0", "1.6.0", "1.5.0"]); + expect(mockFetch).toHaveBeenCalledWith( + expect.stringContaining("hex.pm/api/packages/phoenix"), + ); + }); + it("throws for unsupported registry", async () => { const def = { ...mockDefinition, registry: "cargo" }; await expect(discoverVersions(def)).rejects.toThrow( diff --git a/packages/registry/src/version-check.ts b/packages/registry/src/version-check.ts index 7698195..ace0b17 100644 --- a/packages/registry/src/version-check.ts +++ b/packages/registry/src/version-check.ts @@ -1,5 +1,5 @@ /** - * Version discovery from package registry APIs (npm, pip, maven). + * Version discovery from package registry APIs (npm, pip, maven, hex). * * Queries public registry APIs to find available versions, * filters to defined ranges, and deduplicates to latest-patch-per-minor. diff --git a/registry/hex/elixir.yaml b/registry/hex/elixir.yaml index d29d664..3f729f7 100644 --- a/registry/hex/elixir.yaml +++ b/registry/hex/elixir.yaml @@ -5,4 +5,4 @@ repository: https://github.com/elixir-lang/elixir source: type: git url: https://github.com/elixir-lang/elixir - docs_path: lib + docs_path: lib/elixir/pages diff --git a/registry/hex/phoenix.yaml b/registry/hex/phoenix.yaml index e62cb1d..fe4a64c 100644 --- a/registry/hex/phoenix.yaml +++ b/registry/hex/phoenix.yaml @@ -3,15 +3,7 @@ description: "A productive web framework for building modern web applications in repository: https://github.com/phoenixframework/phoenix versions: - - min_version: "1.7.0" - source: - type: git - url: https://github.com/phoenixframework/phoenix - docs_path: guides - tag_pattern: "v{version}" - - min_version: "1.5.0" - max_version: "1.7.0" source: type: git url: https://github.com/phoenixframework/phoenix diff --git a/registry/hex/phoenix_live_view.yaml b/registry/hex/phoenix_live_view.yaml index 043e017..311676c 100644 --- a/registry/hex/phoenix_live_view.yaml +++ b/registry/hex/phoenix_live_view.yaml @@ -3,15 +3,7 @@ description: "Rich, real-time user experiences with server-rendered HTML in Elix repository: https://github.com/phoenixframework/phoenix_live_view versions: - - min_version: "0.20.0" - source: - type: git - url: https://github.com/phoenixframework/phoenix_live_view - docs_path: guides - tag_pattern: "v{version}" - - min_version: "0.17.0" - max_version: "0.20.0" source: type: git url: https://github.com/phoenixframework/phoenix_live_view