From 7199e57b3551d377384de4d86bb21b747aea8ae4 Mon Sep 17 00:00:00 2001
From: CrazyMax <1951866+crazy-max@users.noreply.github.com>
Date: Thu, 12 Dec 2024 15:28:16 +0100
Subject: [PATCH] make cloud prefix optional to download buildx if driver is
 cloud

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
---
 .github/workflows/ci.yml  |   3 +-
 __tests__/context.test.ts | 134 ++++++++++++++++++++++++++++++++++++++
 src/context.ts            |  14 ++++
 src/main.ts               |   9 +--
 4 files changed, 155 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9c7b235..cea1207 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -25,8 +25,9 @@ jobs:
           - ""
           - "latest"
           - "v0.4.1"
+          - "cloud:latest"
+          - "cloud:v0.11.2-desktop.2"
           - "lab:latest"
-          - "lab:v0.11.2-desktop.2"
     steps:
       -
         name: Checkout
diff --git a/__tests__/context.test.ts b/__tests__/context.test.ts
index 259123f..bfbd804 100644
--- a/__tests__/context.test.ts
+++ b/__tests__/context.test.ts
@@ -323,6 +323,140 @@ describe('getAppendArgs', () => {
   );
 });
 
+describe('getVersion', () => {
+  beforeEach(() => {
+    process.env = Object.keys(process.env).reduce((object, key) => {
+      if (!key.startsWith('INPUT_')) {
+        object[key] = process.env[key];
+      }
+      return object;
+    }, {});
+  });
+
+  // prettier-ignore
+  test.each([
+    [
+      0,
+      new Map<string, string>([
+        // defaults
+        ['install', 'false'],
+        ['use', 'true'],
+        ['cache-binary', 'true'],
+        ['cleanup', 'true'],
+      ]),
+      ''
+    ],
+    [
+      1,
+      new Map<string, string>([
+        ['version', 'latest'],
+        // defaults
+        ['install', 'false'],
+        ['use', 'true'],
+        ['cache-binary', 'true'],
+        ['cleanup', 'true']
+      ]),
+      'latest'
+    ],
+    [
+      2,
+      new Map<string, string>([
+        ['version', 'edge'],
+        // defaults
+        ['install', 'false'],
+        ['use', 'true'],
+        ['cache-binary', 'true'],
+        ['cleanup', 'true']
+      ]),
+      'edge'
+    ],
+    [
+      3,
+      new Map<string, string>([
+        ['version', 'v0.19.2'],
+        // defaults
+        ['install', 'false'],
+        ['use', 'true'],
+        ['cache-binary', 'true'],
+        ['cleanup', 'true']
+      ]),
+      'v0.19.2'
+    ],
+    [
+      4,
+      new Map<string, string>([
+        ['version', 'latest'],
+        ['driver', 'cloud'],
+        // defaults
+        ['install', 'false'],
+        ['use', 'true'],
+        ['cache-binary', 'true'],
+        ['cleanup', 'true']
+      ]),
+      'cloud:latest'
+    ],
+    [
+      5,
+      new Map<string, string>([
+        ['version', 'edge'],
+        ['driver', 'cloud'],
+        // defaults
+        ['install', 'false'],
+        ['use', 'true'],
+        ['cache-binary', 'true'],
+        ['cleanup', 'true']
+      ]),
+      'cloud:edge'
+    ],
+    [
+      6,
+      new Map<string, string>([
+        ['driver', 'cloud'],
+        // defaults
+        ['install', 'false'],
+        ['use', 'true'],
+        ['cache-binary', 'true'],
+        ['cleanup', 'true'],
+      ]),
+      'cloud:latest'
+    ],
+    [
+      7,
+      new Map<string, string>([
+        ['version', 'cloud:v0.11.2-desktop.2'],
+        ['driver', 'cloud'],
+        // defaults
+        ['install', 'false'],
+        ['use', 'true'],
+        ['cache-binary', 'true'],
+        ['cleanup', 'true'],
+      ]),
+      'cloud:v0.11.2-desktop.2'
+    ],
+    [
+      8,
+      new Map<string, string>([
+        ['version', 'cloud:v0.11.2-desktop.2'],
+        // defaults
+        ['install', 'false'],
+        ['use', 'true'],
+        ['cache-binary', 'true'],
+        ['cleanup', 'true'],
+      ]),
+      'cloud:v0.11.2-desktop.2'
+    ],
+  ])(
+    '[%d] given %p as inputs, returns version %p',
+    async (num: number, inputs: Map<string, string>, expected: string) => {
+      inputs.forEach((value: string, name: string) => {
+        setInput(name, value);
+      });
+      const inp = await context.getInputs();
+      expect(context.getVersion(inp)).toEqual(expected);
+    }
+  );
+});
+
 // See: https://github.com/actions/toolkit/blob/master/packages/core/src/core.ts#L67
 function getInputName(name: string): string {
   return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;
diff --git a/src/context.ts b/src/context.ts
index fc09cfb..20b07ec 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -116,3 +116,17 @@ export async function getInspectArgs(inputs: Inputs, toolkit: Toolkit): Promise<
 function driverSupportsBuildkitdFlags(driver: string): boolean {
   return driver == '' || driver == 'docker-container' || driver == 'docker' || driver == 'kubernetes';
 }
+
+export function getVersion(inputs: Inputs): string {
+  const version = inputs.version;
+  if (inputs.driver === 'cloud') {
+    if (!version || version === 'latest') {
+      return 'cloud:latest';
+    }
+    if (version.startsWith('cloud:') || version.startsWith('lab:')) {
+      return version;
+    }
+    return `cloud:${version}`;
+  }
+  return version;
+}
diff --git a/src/main.ts b/src/main.ts
index 698978d..13f0261 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -22,6 +22,7 @@ actionsToolkit.run(
   async () => {
     const inputs: context.Inputs = await context.getInputs();
     stateHelper.setCleanup(inputs.cleanup);
+    const version = context.getVersion(inputs);
 
     const toolkit = new Toolkit();
     const standalone = await toolkit.buildx.isStandalone();
@@ -37,16 +38,16 @@ actionsToolkit.run(
     });
 
     let toolPath;
-    if (Util.isValidRef(inputs.version)) {
+    if (Util.isValidRef(version)) {
       if (standalone) {
         throw new Error(`Cannot build from source without the Docker CLI`);
       }
       await core.group(`Build buildx from source`, async () => {
-        toolPath = await toolkit.buildxInstall.build(inputs.version, !inputs.cacheBinary);
+        toolPath = await toolkit.buildxInstall.build(version, !inputs.cacheBinary);
       });
-    } else if (!(await toolkit.buildx.isAvailable()) || inputs.version) {
+    } else if (!(await toolkit.buildx.isAvailable()) || version) {
       await core.group(`Download buildx from GitHub Releases`, async () => {
-        toolPath = await toolkit.buildxInstall.download(inputs.version || 'latest', !inputs.cacheBinary);
+        toolPath = await toolkit.buildxInstall.download(version || 'latest', !inputs.cacheBinary);
       });
     }
     if (toolPath) {