Compare commits

...

1 Commits
v3 ... v2

Author SHA1 Message Date
Julien Goux
afb1b15109 fix: allow registry fallback in supported CLI versions
The action currently pins every recent CLI to GHCR, which disables the
CLI's registry fallback and leaves image pulls exposed to GHCR
throttling.

Use the installed CLI version to keep the GHCR default for versions
before v2.108.0 and allow fallback for newer versions. Preserve a
caller's explicit registry choice.
2026-09-24 00:20:56 +02:00
3 changed files with 91 additions and 1 deletions

View File

@@ -47,6 +47,8 @@ jobs:
exclude: exclude:
- version: 1.178.2 - version: 1.178.2
pg_major: 17 pg_major: 17
- version: latest
pg_major: 14
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: with:

View File

@@ -12,6 +12,7 @@ const defaultEntrypoint = fileURLToPath(new URL("./main.ts", import.meta.url));
const CLI_CONFIG_REGISTRY = "SUPABASE_INTERNAL_IMAGE_REGISTRY"; const CLI_CONFIG_REGISTRY = "SUPABASE_INTERNAL_IMAGE_REGISTRY";
const GITHUB_RELEASES_API = "https://api.github.com/repos/supabase/cli/releases/latest"; const GITHUB_RELEASES_API = "https://api.github.com/repos/supabase/cli/releases/latest";
const GITHUB_TOKEN_ENV = "SUPABASE_CLI_GITHUB_TOKEN"; const GITHUB_TOKEN_ENV = "SUPABASE_CLI_GITHUB_TOKEN";
const originalCliConfigRegistry = process.env[CLI_CONFIG_REGISTRY];
const originalWorkspace = process.env.GITHUB_WORKSPACE; const originalWorkspace = process.env.GITHUB_WORKSPACE;
const originalGithubToken = process.env[GITHUB_TOKEN_ENV]; const originalGithubToken = process.env[GITHUB_TOKEN_ENV];
const tempDirs = new Set<string>(); const tempDirs = new Set<string>();
@@ -25,6 +26,11 @@ afterEach(() => {
} else { } else {
process.env[GITHUB_TOKEN_ENV] = originalGithubToken; process.env[GITHUB_TOKEN_ENV] = originalGithubToken;
} }
if (originalCliConfigRegistry === undefined) {
delete process.env[CLI_CONFIG_REGISTRY];
} else {
process.env[CLI_CONFIG_REGISTRY] = originalCliConfigRegistry;
}
for (const dir of tempDirs) { for (const dir of tempDirs) {
rmSync(dir, { force: true, recursive: true }); rmSync(dir, { force: true, recursive: true });
@@ -516,6 +522,75 @@ test("explicit version overrides detected root lockfiles", async () => {
expect(spies.setFailed).not.toHaveBeenCalled(); expect(spies.setFailed).not.toHaveBeenCalled();
}); });
test("keeps the GHCR registry pin through Supabase CLI v2.107.x", async () => {
const cliDir = createFakeCli("supabase 2.107.9");
const spies = createActionSpies("2.107.9", cliDir, "/download/v2.107.9/supabase_");
const { run } = await getMainModule();
await run();
expect(spies.exportVariable).toHaveBeenCalledWith(CLI_CONFIG_REGISTRY, "ghcr.io");
expect(spies.setFailed).not.toHaveBeenCalled();
});
test("keeps the GHCR registry pin starting with Supabase CLI v1.28.0", async () => {
const cliDir = createFakeCli("supabase 1.28.0");
const spies = createActionSpies("1.28.0", cliDir, "/download/v1.28.0/supabase_");
const { run } = await getMainModule();
await run();
expect(spies.exportVariable).toHaveBeenCalledWith(CLI_CONFIG_REGISTRY, "ghcr.io");
expect(spies.setFailed).not.toHaveBeenCalled();
});
test("uses the CLI built-in registry fallback starting with Supabase CLI v2.108.0", async () => {
const cliDir = createFakeCli("supabase 2.108.0");
const spies = createActionSpies("2.108.0", cliDir, "/download/v2.108.0/supabase_");
const { run } = await getMainModule();
await run();
expect(spies.exportVariable).not.toHaveBeenCalled();
expect(spies.setFailed).not.toHaveBeenCalled();
});
test("preserves an explicitly configured internal image registry", async () => {
process.env[CLI_CONFIG_REGISTRY] = "registry.example.test";
const cliDir = createFakeCli("supabase 2.108.0");
const spies = createActionSpies("2.108.0", cliDir, "/download/v2.108.0/supabase_");
const { run } = await getMainModule();
await run();
expect(process.env[CLI_CONFIG_REGISTRY]).toBe("registry.example.test");
expect(spies.exportVariable).not.toHaveBeenCalled();
});
test("preserves a whitespace-only internal image registry", async () => {
process.env[CLI_CONFIG_REGISTRY] = " ";
const cliDir = createFakeCli("supabase 2.108.0");
const spies = createActionSpies("2.108.0", cliDir, "/download/v2.108.0/supabase_");
const { run } = await getMainModule();
await run();
expect(process.env[CLI_CONFIG_REGISTRY]).toBe(" ");
expect(spies.exportVariable).not.toHaveBeenCalled();
});
test("uses the installed version to select the registry for latest", async () => {
mockLatestRelease("v2.108.0");
const cliDir = createFakeCli("supabase 2.108.0");
const spies = createActionSpies("latest", cliDir, "/download/v2.108.0/supabase_");
const { run } = await getMainModule();
await run();
expect(spies.exportVariable).not.toHaveBeenCalled();
expect(spies.setFailed).not.toHaveBeenCalled();
});
test("fails when the installed CLI does not report a version", async () => { test("fails when the installed CLI does not report a version", async () => {
process.env.GITHUB_WORKSPACE = createWorkspace({ process.env.GITHUB_WORKSPACE = createWorkspace({
"package-lock.json": createPackageLock("2.46.0"), "package-lock.json": createPackageLock("2.46.0"),

View File

@@ -7,6 +7,7 @@ import { fileURLToPath } from "node:url";
export const CLI_CONFIG_REGISTRY = "SUPABASE_INTERNAL_IMAGE_REGISTRY"; export const CLI_CONFIG_REGISTRY = "SUPABASE_INTERNAL_IMAGE_REGISTRY";
const REGISTRY_VERSION = "1.28.0"; const REGISTRY_VERSION = "1.28.0";
const DEFAULT_REGISTRY_FALLBACK_VERSION = "2.108.0";
const VERSIONED_ARCHIVE_VERSION = "2.99.0"; const VERSIONED_ARCHIVE_VERSION = "2.99.0";
const DEFAULT_VERSION = "latest"; const DEFAULT_VERSION = "latest";
const GITHUB_RELEASES_API = "https://api.github.com/repos/supabase/cli/releases/latest"; const GITHUB_RELEASES_API = "https://api.github.com/repos/supabase/cli/releases/latest";
@@ -328,7 +329,19 @@ export async function run(): Promise<void> {
core.setOutput("version", installedVersion); core.setOutput("version", installedVersion);
core.addPath(cliPath); core.addPath(cliPath);
if (version.toLowerCase() === "latest" || semver.order(version, REGISTRY_VERSION) >= 0) { if (process.env[CLI_CONFIG_REGISTRY]) {
return;
}
const installedVersionNumber = extractConcreteVersion(installedVersion);
if (!installedVersionNumber) {
throw new Error("Could not determine installed Supabase CLI version");
}
if (
semver.order(installedVersionNumber, REGISTRY_VERSION) >= 0 &&
semver.order(installedVersionNumber, DEFAULT_REGISTRY_FALLBACK_VERSION) === -1
) {
core.exportVariable(CLI_CONFIG_REGISTRY, "ghcr.io"); core.exportVariable(CLI_CONFIG_REGISTRY, "ghcr.io");
} }
} catch (error) { } catch (error) {