From fef7975ba3457289440d385e1fb73b9d42b878d7 Mon Sep 17 00:00:00 2001
From: Alexandre 'Kidev' Poumaroux <1204936+Kidev@users.noreply.github.com>
Date: Wed, 18 Dec 2024 03:08:49 +0100
Subject: [PATCH 1/7] To fix issues with Qt 6.7+ and match with aqtinstall,
 allows 'all_os' as host and 'wasm' as target

---
 README.md          |  9 +++++++--
 action/src/main.ts | 18 ++++++++++++------
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index f613350b..be43aeed 100644
--- a/README.md
+++ b/README.md
@@ -32,14 +32,14 @@ This is the host platform of the Qt version you will be installing. It's unlikel
 
 For example, if you are building on Linux and targeting desktop, you would set host to `linux`. If you are building on Linux and targeting android, you would set host to `linux` also. The host platform is the platform that your application will build on, not its target platform.
 
-Possible values: `windows`, `mac`, or `linux`
+Possible values: `windows`, `mac`, `linux` or `all_os`
 
 Defaults to the current platform it is being run on.
 
 ### `target`
 This is the target platform that you will be building for. You will want to set this if you are building for iOS or Android. Please note that iOS builds are supported only on macOS hosts and Win RT builds are only supported on Windows hosts.
 
-Possible values: `desktop`, `android`, `ios`, or `winrt`
+Possible values: `desktop`, `android`, `ios`, `winrt` or `wasm`
 
 Default: `desktop`
 
@@ -66,6 +66,8 @@ Windows w/ Qt >= 6.8: `win64_msvc2022_64`
 
 Android: `android_armv7`
 
+WASM: `wasm_singlethread`
+
 ### `dir`
 This is the directory prefix that Qt will be installed to.
 
@@ -255,9 +257,12 @@ Default: `==0.20.*`
 
 ### `extra`
 This input can be used to append arguments to the end of the aqtinstall command for any special purpose.
+It is useful with WASM builds using `--autodesktop` as it allows the automatic installation of the required Qt for the host.
 
 Example value: `--external 7z`
 
+For WASM: `--autodesktop`
+
 ## Example with all arguments
 
 ```yml
diff --git a/action/src/main.ts b/action/src/main.ts
index 4aac05d2..6abfe61f 100644
--- a/action/src/main.ts
+++ b/action/src/main.ts
@@ -104,8 +104,8 @@ const isAutodesktopSupported = async (): Promise<boolean> => {
 };
 
 class Inputs {
-  readonly host: "windows" | "mac" | "linux";
-  readonly target: "desktop" | "android" | "ios";
+  readonly host: "windows" | "mac" | "linux" | "all_os";
+  readonly target: "desktop" | "android" | "ios" | "wasm";
   readonly version: string;
   readonly arch: string;
   readonly dir: string;
@@ -156,19 +156,19 @@ class Inputs {
       }
     } else {
       // Make sure host is one of the allowed values
-      if (host === "windows" || host === "mac" || host === "linux") {
+      if (host === "windows" || host === "mac" || host === "linux" || host === "all_os") {
         this.host = host;
       } else {
-        throw TypeError(`host: "${host}" is not one of "windows" | "mac" | "linux"`);
+        throw TypeError(`host: "${host}" is not one of "windows" | "mac" | "linux" | "all_os"`);
       }
     }
 
     const target = core.getInput("target");
     // Make sure target is one of the allowed values
-    if (target === "desktop" || target === "android" || target === "ios") {
+    if (target === "desktop" || target === "android" || target === "ios" || target === "wasm") {
       this.target = target;
     } else {
-      throw TypeError(`target: "${target}" is not one of "desktop" | "android" | "ios"`);
+      throw TypeError(`target: "${target}" is not one of "desktop" | "android" | "ios" | "wasm"`);
     }
 
     // An attempt to sanitize non-straightforward version number input
@@ -186,6 +186,12 @@ class Inputs {
         } else {
           this.arch = "android_armv7";
         }
+      } else if (this.target === "wasm") {
+        if (compareVersions(this.version, ">=", "6.0.0")) {
+          this.arch = "wasm_singlethread";
+        } else {
+          this.arch = "wasm_32";
+        }
       } else if (this.host === "windows") {
         if (compareVersions(this.version, ">=", "6.8.0")) {
           this.arch = "win64_msvc2022_64";

From 0a2cd94cfff4562eb83bdb667af542932ba7fb10 Mon Sep 17 00:00:00 2001
From: Alexandre Poumaroux <1204936+Kidev@users.noreply.github.com>
Date: Wed, 25 Dec 2024 05:44:37 +0100
Subject: [PATCH 2/7] Update README.md

---
 README.md | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/README.md b/README.md
index be43aeed..77888498 100644
--- a/README.md
+++ b/README.md
@@ -257,12 +257,9 @@ Default: `==0.20.*`
 
 ### `extra`
 This input can be used to append arguments to the end of the aqtinstall command for any special purpose.
-It is useful with WASM builds using `--autodesktop` as it allows the automatic installation of the required Qt for the host.
 
 Example value: `--external 7z`
 
-For WASM: `--autodesktop`
-
 ## Example with all arguments
 
 ```yml

From 15aa965d2de8709e1cacadbb765394fb4e1ee2cc Mon Sep 17 00:00:00 2001
From: Alexandre Poumaroux <1204936+Kidev@users.noreply.github.com>
Date: Mon, 6 Jan 2025 08:04:25 +0100
Subject: [PATCH 3/7] Update main.ts

---
 action/src/main.ts | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/action/src/main.ts b/action/src/main.ts
index 6abfe61f..cb14bd26 100644
--- a/action/src/main.ts
+++ b/action/src/main.ts
@@ -186,12 +186,6 @@ class Inputs {
         } else {
           this.arch = "android_armv7";
         }
-      } else if (this.target === "wasm") {
-        if (compareVersions(this.version, ">=", "6.0.0")) {
-          this.arch = "wasm_singlethread";
-        } else {
-          this.arch = "wasm_32";
-        }
       } else if (this.host === "windows") {
         if (compareVersions(this.version, ">=", "6.8.0")) {
           this.arch = "win64_msvc2022_64";

From 8364bca6c28b1b327b2d37ecb3f5e3cfae37bd3b Mon Sep 17 00:00:00 2001
From: Alexandre Poumaroux <1204936+Kidev@users.noreply.github.com>
Date: Mon, 6 Jan 2025 08:10:41 +0100
Subject: [PATCH 4/7] Update action.yml

---
 action/action.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/action/action.yml b/action/action.yml
index ebee8ac5..fca7d90a 100644
--- a/action/action.yml
+++ b/action/action.yml
@@ -9,7 +9,7 @@ inputs:
     description: Directory to install Qt
   version:
     description: Version of Qt to install
-    default: "5.15.2"
+    default: "6.8.1"
   host:
     description: Host platform
   target:
@@ -52,7 +52,7 @@ inputs:
     description: Location to source aqtinstall from in case of issues
   aqtversion:
     description: Version of aqtinstall to use in case of issues
-    default: ==3.1.*
+    default: ==3.2.*
   py7zrversion:
     description: Version of py7zr to use in case of issues
     default: ==0.20.*

From f4beefabbaacd1a3d619c7dafb71ebe69279078e Mon Sep 17 00:00:00 2001
From: Alexandre Poumaroux <1204936+Kidev@users.noreply.github.com>
Date: Mon, 6 Jan 2025 08:11:32 +0100
Subject: [PATCH 5/7] Update action.yml

---
 action.yml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/action.yml b/action.yml
index 40b633e8..9c4d9960 100644
--- a/action.yml
+++ b/action.yml
@@ -9,7 +9,7 @@ inputs:
     description: Directory to install Qt
   version:
     description: Version of Qt to install
-    default: "5.15.2"
+    default: "6.8.1"
   host:
     description: Host platform
   target:
@@ -55,7 +55,7 @@ inputs:
     description: Location to source aqtinstall from in case of issues
   aqtversion:
     description: Version of aqtinstall to use in case of issues
-    default: ==3.1.*
+    default: ==3.2.*
   py7zrversion:
     description: Version of py7zr to use in case of issues
     default: ==0.20.*
@@ -87,7 +87,7 @@ runs:
     if: ${{ inputs.setup-python  == 'true' }}
     uses: actions/setup-python@v5
     with:
-      python-version: '3.6.x - 3.11.x'
+      python-version: '3.6.x - 3.12.x'
 
   - name: Setup and run aqtinstall
     uses: ./action
@@ -118,4 +118,4 @@ runs:
       examples: ${{ inputs.examples }}
       example-archives: ${{ inputs.example-archives }}
       example-modules: ${{ inputs.example-modules }}
-      extra: ${{ inputs.extra }}
\ No newline at end of file
+      extra: ${{ inputs.extra }}

From 445a83339b4cb7fb992b20490ade7f15af1ac4ba Mon Sep 17 00:00:00 2001
From: Alexandre Poumaroux <1204936+Kidev@users.noreply.github.com>
Date: Mon, 6 Jan 2025 08:17:05 +0100
Subject: [PATCH 6/7] Update README.md

---
 README.md | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index 77888498..d7789cd2 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ The desired version of Qt to install.
 
 You can also pass in SimpleSpec version numbers, for example `6.2.*`.
 
-Default: `5.15.2` (Last Qt 5 LTS)
+Default: `6.8.1` (Last Qt 6 LTS)
 
 **Please note that for Linux builds, Qt 6+ requires Ubuntu 20.04 or later.**
 
@@ -66,8 +66,6 @@ Windows w/ Qt >= 6.8: `win64_msvc2022_64`
 
 Android: `android_armv7`
 
-WASM: `wasm_singlethread`
-
 ### `dir`
 This is the directory prefix that Qt will be installed to.
 
@@ -248,7 +246,7 @@ By default this is unset and ignored.
 
 Version of [aqtinstall](https://github.com/miurahr/aqtinstall) to use, given in the format used by pip, for example: `==0.7.1`, `>=0.7.1`, `==0.7.*`. This is intended to be used to troubleshoot any bugs that might be caused or fixed by certain versions of aqtinstall.
 
-Default: `==3.1.*`
+Default: `==3.2.*`
 
 ### `py7zrversion`
 Version of py7zr in the same style as the aqtversion and intended to be used for the same purpose.
@@ -266,10 +264,10 @@ Example value: `--external 7z`
     - name: Install Qt
       uses: jurplel/install-qt-action@v4
       with:
-        version: '5.15.2'
+        version: '6.8.1'
         host: 'windows'
         target: 'desktop'
-        arch: 'win64_msvc2019_64'
+        arch: 'win64_msvc2022_64'
         dir: '${{ github.workspace }}/example/'
         install-deps: 'true'
         modules: 'qtcharts qtwebengine'
@@ -280,7 +278,7 @@ Example value: `--external 7z`
         tools: 'tools_ifw tools_qtcreator,qt.tools.qtcreator'
         set-env: 'true'
         tools-only: 'false'
-        aqtversion: '==3.1.*'
+        aqtversion: '==3.2.*'
         py7zrversion: '==0.20.*'
         extra: '--external 7z'
 ```

From 714de7355b5e42aef0f7182d35750b7fb752ec22 Mon Sep 17 00:00:00 2001
From: Alexandre 'Kidev' Poumaroux <1204936+Kidev@users.noreply.github.com>
Date: Mon, 27 Jan 2025 06:29:12 +0100
Subject: [PATCH 7/7] Add commercial support

---
 README.md          |  26 ++++++++++++
 action.yml         |  16 ++++++-
 action/action.yml  |  11 ++++-
 action/src/main.ts | 102 ++++++++++++++++++++++++++++++++++++++-------
 4 files changed, 138 insertions(+), 17 deletions(-)

diff --git a/README.md b/README.md
index d7789cd2..6332db37 100644
--- a/README.md
+++ b/README.md
@@ -74,6 +74,32 @@ When possible, access your Qt directory through the `QT_ROOT_DIR` environment va
 
 Default: `$RUNNER_WORKSPACE` (this is one folder above the starting directory)
 
+### `use-commercial` (since `v4.3.0`)
+Whether or not to use `aqtinstall` to install Qt using its official online installer enabling the commercial versions for those owning a license.
+For this to work, you need to also set `aqtsource` to `git+https://github.com/Kidev/aqtinstall.git@install_qt_commercial`.
+The parameter `host` will then be ignored, as you can only install commercial Qt versions on the OS running the installer.
+Example:
+```yml
+    - name: Install Qt
+      uses: jurplel/install-qt-action@v4
+      with:
+        version: '5.15.3'
+        target: 'desktop'
+        arch: 'win64_msvc2019_64'
+        aqtsource: 'git+https://github.com/Kidev/aqtinstall.git@install_qt_commercial'
+        use-commercial: true
+        user: '****@gmail.com'
+        password: '****'
+```
+
+Default: `false`
+
+#### `user`
+If `use-commercial` is true, will use this username/email to authenticate with Qt servers
+
+#### `password`
+If `use-commercial` is true, will use this password to authenticate with Qt servers
+
 ### `install-deps`
 Whether or not to automatically install Qt dependencies on Linux through `apt`.
 
diff --git a/action.yml b/action.yml
index 9c4d9960..635aeded 100644
--- a/action.yml
+++ b/action.yml
@@ -58,7 +58,7 @@ inputs:
     default: ==3.2.*
   py7zrversion:
     description: Version of py7zr to use in case of issues
-    default: ==0.20.*
+    default: ==0.22.*
   extra:
     description: Any extra arguments to append to the back
   source:
@@ -80,6 +80,15 @@ inputs:
     description: Space-separated list of .7z example archives to install. Used to reduce download/image sizes.
   example-modules:
     description: Space-separated list of additional example modules to install.
+  use-commercial:
+    default: false
+    description: Whether or not to use aqtinstall to install the commercial version of Qt
+  user:
+    default: 'username'
+    description: Your Qt username
+  password:
+    default: 'password'
+    description: Your Qt password
 runs:
   using: "composite"
   steps:
@@ -87,7 +96,7 @@ runs:
     if: ${{ inputs.setup-python  == 'true' }}
     uses: actions/setup-python@v5
     with:
-      python-version: '3.6.x - 3.12.x'
+      python-version: '3.6.x - 3.13.x'
 
   - name: Setup and run aqtinstall
     uses: ./action
@@ -119,3 +128,6 @@ runs:
       example-archives: ${{ inputs.example-archives }}
       example-modules: ${{ inputs.example-modules }}
       extra: ${{ inputs.extra }}
+      use-commercial: ${{ inputs.use-commercial }}
+      user: ${{ inputs.user }}
+      password: ${{ inputs.password }}
diff --git a/action/action.yml b/action/action.yml
index fca7d90a..ec481e73 100644
--- a/action/action.yml
+++ b/action/action.yml
@@ -55,7 +55,7 @@ inputs:
     default: ==3.2.*
   py7zrversion:
     description: Version of py7zr to use in case of issues
-    default: ==0.20.*
+    default: ==0.22.*
   extra:
     description: Any extra arguments to append to the back
   source:
@@ -77,6 +77,15 @@ inputs:
     description: Space-separated list of .7z example archives to install. Used to reduce download/image sizes.
   example-modules:
     description: Space-separated list of additional example modules to install.
+  use-commercial:
+    default: false
+    description: Whether or not to use aqtinstall to install the commercial version of Qt
+  user:
+    default: 'username'
+    description: Your Qt username
+  password:
+    default: 'password'
+    description: Your Qt password
 runs:
   using: node20
   main: lib/main.js
diff --git a/action/src/main.ts b/action/src/main.ts
index cb14bd26..f71aa647 100644
--- a/action/src/main.ts
+++ b/action/src/main.ts
@@ -56,6 +56,7 @@ const pythonCommand = (command: string, args: readonly string[]): string => {
   const python = process.platform === "win32" ? "python" : "python3";
   return `${python} -m ${command} ${args.join(" ")}`;
 };
+
 const execPython = async (command: string, args: readonly string[]): Promise<number> => {
   return exec(pythonCommand(command, args));
 };
@@ -97,6 +98,55 @@ const locateQtArchDir = (installDir: string): string => {
   }
 };
 
+const locateQtWasmHostArchDir = (
+  installDir: string,
+  hostType: "windows" | "mac" | "linux" | "all_os",
+  target: "desktop" | "android" | "ios" | "wasm",
+  version: string
+): string => {
+  // For WASM in all_os mode, use the host builder directory
+  if (hostType === "all_os" && target === "wasm") {
+    const versionDir = path.join(installDir, version);
+
+    switch (process.platform) {
+      case "win32": {
+        // Find mingw directories
+        const mingwPattern = /^win\d+_mingw\d+$/;
+        const mingwArches = glob
+          .sync(`${versionDir}/*/`)
+          .map((dir) => path.basename(dir))
+          .filter((dir) => mingwPattern.test(dir))
+          .sort((a, b) => {
+            const [aBits, aVer] = a
+              .match(/win(\d+)_mingw(\d+)/)
+              ?.slice(1)
+              .map(Number) ?? [0, 0];
+            const [bBits, bVer] = b
+              .match(/win(\d+)_mingw(\d+)/)
+              ?.slice(1)
+              .map(Number) ?? [0, 0];
+            if (aBits !== bBits) return bBits - aBits;
+            return bVer - aVer;
+          });
+
+        if (!mingwArches.length) {
+          throw Error(`Failed to locate a MinGW directory for WASM host in ${versionDir}`);
+        }
+        return path.join(versionDir, mingwArches[0]);
+      }
+      case "darwin":
+        return path.join(versionDir, "clang_64");
+      default:
+        return path.join(
+          versionDir,
+          compareVersions(version, ">=", "6.7.0") ? "linux_gcc_64" : "gcc_64"
+        );
+    }
+  }
+
+  return locateQtArchDir(installDir);
+};
+
 const isAutodesktopSupported = async (): Promise<boolean> => {
   const rawOutput = await getPythonOutput("aqt", ["version"]);
   const match = rawOutput.match(/aqtinstall\(aqt\)\s+v(\d+\.\d+\.\d+)/);
@@ -136,6 +186,10 @@ class Inputs {
   readonly aqtVersion: string;
   readonly py7zrVersion: string;
 
+  readonly useCommercial: boolean;
+  readonly user: string;
+  readonly password: string;
+
   constructor() {
     const host = core.getInput("host");
     // Set host automatically if omitted
@@ -242,6 +296,10 @@ class Inputs {
 
     this.py7zrVersion = core.getInput("py7zrversion");
 
+    this.useCommercial = Inputs.getBoolInput("use-commercial");
+    this.user = core.getInput("user");
+    this.password = core.getInput("password");
+
     this.src = Inputs.getBoolInput("source");
     this.srcArchives = Inputs.getStringArrayInput("src-archives");
 
@@ -267,6 +325,7 @@ class Inputs {
         this.py7zrVersion,
         this.aqtSource,
         this.aqtVersion,
+        this.useCommercial ? "commercial" : "",
       ],
       this.modules,
       this.archives,
@@ -386,19 +445,34 @@ const run = async (): Promise<void> => {
 
     // Install Qt
     if (inputs.isInstallQtBinaries) {
-      const qtArgs = [
-        inputs.host,
-        inputs.target,
-        inputs.version,
-        ...(inputs.arch ? [inputs.arch] : []),
-        ...autodesktop,
-        ...["--outputdir", inputs.dir],
-        ...flaggedList("--modules", inputs.modules),
-        ...flaggedList("--archives", inputs.archives),
-        ...inputs.extra,
-      ];
-
-      await execPython("aqt install-qt", qtArgs);
+      if (inputs.useCommercial && inputs.user && inputs.password) {
+        const qtArgs = [
+          "install-qt-commercial",
+          inputs.target,
+          ...(inputs.arch ? [inputs.arch] : []),
+          inputs.version,
+          ...["--outputdir", inputs.dir],
+          ...["--user", inputs.user],
+          ...["--password", inputs.password],
+          ...flaggedList("--modules", inputs.modules),
+          ...inputs.extra,
+        ];
+        await execPython("aqt", qtArgs);
+      } else {
+        const qtArgs = [
+          "install-qt",
+          inputs.host,
+          inputs.target,
+          inputs.version,
+          ...(inputs.arch ? [inputs.arch] : []),
+          ...autodesktop,
+          ...["--outputdir", inputs.dir],
+          ...flaggedList("--modules", inputs.modules),
+          ...flaggedList("--archives", inputs.archives),
+          ...inputs.extra,
+        ];
+        await execPython("aqt", qtArgs);
+      }
     }
 
     const installSrcDocExamples = async (
@@ -455,7 +529,7 @@ const run = async (): Promise<void> => {
   }
   // Set environment variables/outputs for binaries
   if (inputs.isInstallQtBinaries) {
-    const qtPath = locateQtArchDir(inputs.dir);
+    const qtPath = locateQtWasmHostArchDir(inputs.dir, inputs.host, inputs.target, inputs.version);
     // Set outputs
     core.setOutput("qtPath", qtPath);