name: Build WSA
on:
  push:
  pull_request:
  workflow_dispatch:
    inputs:
      magisk_apk:
        description: "Download link to magisk apk."
        required: true
        default: "https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-debug.apk"
      gapps_variant:
        description: "Variants of gapps. Should be: [none, aroma, super, stock, full, mini, micro, nano, pico, tvstock, tvmini]"
        required: true
        default: "none"
      root_sol:
        description: "Root soluction. Should be: [magisk, none]"
        required: true
        default: "magisk"

jobs:
  build:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        arch: [x64, arm64]
    steps:
      - name: Dependencies
        run: |
          pip3 install beautifulsoup4 lxml
          sudo apt-get update && sudo apt-get install setools lzip qemu-utils wine winetricks
          wget -qO- "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/archive/$GITHUB_REF.tar.gz" | sudo tar --wildcards -zxvf- -C ~ --strip-component=2 '*/wine/*'
          winetricks msxml6
      - name: Download WSA
        shell: python
        run: |
          import requests
          from bs4 import BeautifulSoup
          import re
          import zipfile
          import os
          import urllib.request

          arch = "${{ matrix.arch }}"

          res = requests.post("https://store.rg-adguard.net/api/GetFiles", "type=CategoryId&url=858014f3-3934-4abe-8078-4aa193e74ca8&ring=WIS&lang=en-US", headers={
              "content-type": "application/x-www-form-urlencoded"
          })
          html = BeautifulSoup(res.content, "lxml")

          a = html.find("a", string=re.compile(f"Microsoft\.UI\.Xaml\..*_{arch}_.*\.appx"))
          link = a["href"]
          print(f"downloading link: {link}", flush=True)
          out_file = "xaml.appx"
          if not os.path.isfile(out_file):
              urllib.request.urlretrieve(link, out_file)

          a = html.find("a", string=re.compile(f"Microsoft\.VCLibs\..*_{arch}_.*\.appx"))
          link = a["href"]
          print(f"downloading link: {link}", flush=True)
          out_file = "vclibs.appx"
          if not os.path.isfile(out_file):
              urllib.request.urlretrieve(link, out_file)

          a = html.find("a", string=re.compile("MicrosoftCorporationII\.WindowsSubsystemForAndroid_.*\.msixbundle"))
          link = a["href"]
          print(f"downloading link: {link}", flush=True)
          out_file = "wsa.zip"
          if not os.path.isfile(out_file):
              urllib.request.urlretrieve(link, out_file)

          zip_name = ""
          with zipfile.ZipFile(out_file) as zip:
              for f in zip.filelist:
                  if arch in f.filename.lower():
                      zip_name = f.filename
                      if not os.path.isfile(zip_name):
                          print(f"unzipping to {zip_name}", flush=True)
                          zip.extract(f)
                          ver_no = zip_name.split("_")
                          ver = ver_no[1]
                          with open(os.environ['GITHUB_ENV'], 'a') as g:
                              g.write(f'WSA_VER={ver}\n')
                          rel = ver_no[3].split(".")
                          rell = str(rel[0])
                          with open(os.environ['GITHUB_ENV'], 'a') as g:
                              g.write(f'WSA_REL={rell}\n')
                  if 'language' in f.filename.lower() or 'scale' in f.filename.lower():
                      name = f.filename.split("-", 1)[1].split(".")[0]
                      zip.extract(f)
                      with zipfile.ZipFile(f.filename) as l:
                          for g in l.filelist:
                              if g.filename == 'resources.pri':
                                  g.filename = f'{name}.pri'
                                  l.extract(g, 'pri')
                                  print(f"extract resource pack {g.filename}")
                              elif g.filename == 'AppxManifest.xml':
                                  g.filename = f'{name}.xml'
                                  l.extract(g, 'xml')

          with zipfile.ZipFile(zip_name) as zip:
              if not os.path.isdir(arch):
                  print(f"unzipping from {zip_name}", flush=True)
                  zip.extractall(arch)

          print("done", flush=True)
      - name: Download Magisk
        shell: python
        run: |
          import urllib.request
          import zipfile
          import os

          magisk_apk = """${{ github.event.inputs.magisk_apk }}"""

          if not magisk_apk:
              magisk_apk = """https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-debug.apk"""

          out_file = "magisk.zip"

          arch = "${{ matrix.arch }}"

          abi_map={"x64" : ["x86_64", "x86"], "arm64" : ["arm64-v8a", "armeabi-v7a"]}

          if not os.path.isfile(out_file):
              urllib.request.urlretrieve(magisk_apk, out_file)

          def extract_as(zip, name, as_name, dir):
              info = zip.getinfo(name)
              info.filename = as_name
              zip.extract(info, dir)

          with zipfile.ZipFile(out_file) as zip:
              extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagisk64.so", "magisk64", "magisk")
              extract_as(zip, f"lib/{ abi_map[arch][1] }/libmagisk32.so", "magisk32", "magisk")
              extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskinit", "magisk")
              extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskpolicy", "magisk")
              extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskboot.so", "magiskboot", "magisk")
              extract_as(zip, f"lib/{ abi_map[arch][0] }/libbusybox.so", "busybox", "magisk")
              extract_as(zip, f"lib/{ abi_map['x64'][0] }/libmagiskinit.so", "magiskpolicy", ".")
              extract_as(zip, f"assets/boot_patch.sh", "boot_patch.sh", "magisk")
              extract_as(zip, f"assets/util_functions.sh", "util_functions.sh", "magisk")
      - name: Download OpenGApps
        if: ${{ github.event.inputs.gapps_variant != 'none' && github.event.inputs.gapps_variant != '' }}
        shell: python
        run: |
          import requests
          import zipfile
          import os
          import urllib.request
          import json

          arch = "${{ matrix.arch }}"
          variant = "${{ github.event.inputs.gapps_variant }}"
          abi_map = {"x64" : "x86_64", "arm64": "arm64"}

          res = requests.get(f"https://api.opengapps.org/list")

          j = json.loads(res.content)

          link = {i["name"]: i for i in j["archs"][abi_map[arch]]["apis"]["11.0"]["variants"]}[variant]["zip"]

          print(f"downloading link: {link}", flush=True)

          out_file = "gapps.zip"

          if not os.path.isfile(out_file):
              urllib.request.urlretrieve(link, out_file)
          print("done", flush=True)

      - name: Extract GApps and expand images
        if: ${{ github.event.inputs.gapps_variant != 'none' && github.event.inputs.gapps_variant != '' }}
        run: |
          mkdir gapps
          unzip -p gapps.zip {Core,GApps}/'*.lz' | tar --lzip -C gapps -xvf - -i --strip-components=2 --exclude='setupwizardtablet-x86_64' --exclude='packageinstallergoogle-all' --exclude='speech-common' --exclude='markup-lib-arm' --exclude='markup-lib-arm64' --exclude='markup-all' --exclude='setupwizarddefault-x86_64' --exclude='pixellauncher-all' --exclude='pixellauncher-common'

          e2fsck -yf ${{ matrix.arch }}/system.img
          resize2fs ${{ matrix.arch }}/system.img $(( $(du -sB512 gapps | cut -f1) + $(du -sB512 ${{ matrix.arch }}/system.img | cut -f1) ))s
          e2fsck -yf ${{ matrix.arch }}/product.img
          resize2fs ${{ matrix.arch }}/product.img 1024M
          e2fsck -yf ${{ matrix.arch }}/system_ext.img
          resize2fs ${{ matrix.arch }}/system_ext.img 108M
      - name: Expand vendor
        run: |
          e2fsck -yf ${{ matrix.arch }}/vendor.img
          resize2fs ${{ matrix.arch }}/vendor.img 320M
      - name: Mount images
        run: |
          sudo mkdir system
          sudo mkdir userdata
          sudo mount -o loop ${{ matrix.arch }}/system.img system
          sudo mount -o loop ${{ matrix.arch }}/vendor.img system/vendor
          sudo mount -o loop ${{ matrix.arch }}/product.img system/product
          sudo mount -o loop ${{ matrix.arch }}/system_ext.img system/system_ext
          qemu-img convert -O raw ${{ matrix.arch }}/userdata.vhdx userdata.img
          sudo mount -o loop userdata.img userdata
      - name: Integrate Magisk
        if: ${{ github.event.inputs.root_sol == 'magisk' || github.event.inputs.root_sol == '' }}
        run: |
          sudo mkdir system/sbin
          sudo chcon --reference system/init.environ.rc system/sbin
          sudo chown root:root system/sbin
          sudo chmod 0700 system/sbin
          sudo cp magisk/* system/sbin/
          sudo mkdir -p userdata/adb/magisk
          sudo chmod -R 700 userdata/adb
          sudo cp magisk/* userdata/adb/magisk/
          sudo find userdata/adb/magisk -type f -exec chmod 0755 {} \;
          sudo cp magisk.zip userdata/adb/magisk/magisk.apk
          sudo tee -a system/sbin/loadpolicy.sh <<EOF
          #!/system/bin/sh
          restorecon -R /data/adb/magisk
          for module in $(ls /data/adb/modules); do
              if ! [ -f "/data/adb/modules/$module/disable" ] && [ -f "/data/adb/modules/$module/sepolicy.rule" ]; then
                  /sbin/magiskpolicy --live --apply "/data/adb/modules/$module/sepolicy.rule"
              fi
          done
          EOF
          sudo find system/sbin -type f -exec chmod 0755 {} \;
          sudo find system/sbin -type f -exec chown root:root {} \;
          sudo find system/sbin -type f -exec chcon --reference system/product {} \;
          chmod +x ./magiskpolicy
          echo '/dev/wsa-magisk(/.*)?    u:object_r:magisk_file:s0' | sudo tee -a system/vendor/etc/selinux/vendor_file_contexts
          echo '/data/adb/magisk(/.*)?   u:object_r:magisk_file:s0' | sudo tee -a system/vendor/etc/selinux/vendor_file_contexts
          sudo ./magiskpolicy --load system/vendor/etc/selinux/precompiled_sepolicy --save system/vendor/etc/selinux/precompiled_sepolicy --magisk "allow * magisk_file lnk_file *"
          sudo tee -a system/system/etc/init/hw/init.rc <<EOF

          on post-fs-data
              start logd
              start adbd
              mkdir /dev/wsa-magisk
              mount tmpfs tmpfs /dev/wsa-magisk mode=0755
              copy /sbin/magisk64 /dev/wsa-magisk/magisk64
              chmod 0755 /dev/wsa-magisk/magisk64
              symlink ./magisk64 /dev/wsa-magisk/magisk
              symlink ./magisk64 /dev/wsa-magisk/su
              symlink ./magisk64 /dev/wsa-magisk/resetprop
              copy /sbin/magisk32 /dev/wsa-magisk/magisk32
              chmod 0755 /dev/wsa-magisk/magisk32
              copy /sbin/magiskinit /dev/wsa-magisk/magiskinit
              chmod 0755 /dev/wsa-magisk/magiskinit
              symlink ./magiskinit /dev/wsa-magisk/magiskpolicy
              mkdir /dev/wsa-magisk/.magisk 700
              mkdir /dev/wsa-magisk/.magisk/mirror 700
              mkdir /dev/wsa-magisk/.magisk/block 700
              rm /dev/.magisk_unblock
              start IhhslLhHYfse
              start FAhW7H9G5sf
              wait /dev/.magisk_unblock 40
              rm /dev/.magisk_unblock

          service IhhslLhHYfse /system/bin/sh /sbin/loadpolicy.sh
              user root
              seclabel u:r:magisk:s0
              oneshot

          service FAhW7H9G5sf /dev/wsa-magisk/magisk --post-fs-data
              user root
              seclabel u:r:magisk:s0
              oneshot

          service HLiFsR1HtIXVN6 /dev/wsa-magisk/magisk --service
              class late_start
              user root
              seclabel u:r:magisk:s0
              oneshot

          on property:sys.boot_completed=1
              start YqCTLTppv3ML

          service YqCTLTppv3ML /dev/wsa-magisk/magisk --boot-complete
              user root
              seclabel u:r:magisk:s0
              oneshot
          EOF
      - name: Merge Language Resources
        run: |
          cp ${{ matrix.arch }}/resources.pri pri/en-us.pri
          cp ${{ matrix.arch }}/AppxManifest.xml xml/en-us.xml
          tee priconfig.xml <<EOF
          <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
          <resources targetOsVersion="10.0.0" majorVersion="1">
              <index root="\" startIndexAt="\">
                  <indexer-config type="folder" foldernameAsQualifier="true" filenameAsQualifier="true" qualifierDelimiter="."/>
                  <indexer-config type="PRI"/>
              </index>
          </resources>
          EOF
          wine64 ~/makepri.exe new /pr pri /in MicrosoftCorporationII.WindowsSubsystemForAndroid /cf priconfig.xml /of ${{ matrix.arch }}/resources.pri /o
          sed -i -zE "s/<Resources.*Resources>/<Resources>\n$(cat xml/* | grep -Po '<Resource [^>]*/>' | sed ':a;N;$!ba;s/\n/\\n/g' | sed 's/\$/\\$/g' | sed 's/\//\\\//g')\n<\/Resources>/g" ${{ matrix.arch }}/AppxManifest.xml
      - name: Add extra packages
        run: |
          wget -qO- "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/archive/$GITHUB_REF.tar.gz" | sudo tar --wildcards -zxvf- --strip-component=2 '*/${{ matrix.arch }}/system/*'
          sudo find system/system/priv-app -type d -exec chmod 0755 {} \;
          sudo find system/system/priv-app -type f -exec chmod 0644 {} \;
          sudo find system/system/priv-app -exec chcon --reference=system/system/priv-app {} \;
      - name: Integrate GApps
        if: ${{ github.event.inputs.gapps_variant != 'none' && github.event.inputs.gapps_variant != '' }}
        run: |
          wget -qO- "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/archive/$GITHUB_REF.tar.gz" | sudo tar --wildcards -zxvf- --strip-component=2 '*/${{ matrix.arch }}/gapps/*'
          shopt -s extglob
          sudo cp -vr gapps/!(product) system/system
          sudo cp -vr gapps/product/* system/product/

          sudo find system/system/{app,etc,framework,priv-app} -exec chown root:root {} \;
          sudo find system/product/{app,etc,overlay,priv-app} -exec chown root:root {} \;

          sudo find system/system/{app,etc,framework,priv-app} -type d -exec chmod 0755 {} \;
          sudo find system/product/{app,etc,overlay,priv-app} -type d -exec chmod 0755 {} \;

          sudo find system/system/{app,framework,priv-app} -type f -exec chmod 0644 {} \;
          ls gapps/etc/ | xargs -n 1 -I dir sudo find system/system/etc/dir -type f -exec chmod 0644 {} \;
          sudo find system/product/{app,etc,overlay,priv-app} -type f -exec chmod 0644 {} \;

          sudo find system/system/{app,framework,priv-app} -type d -exec chcon --reference=system/system/app {} \;
          sudo find system/product/{app,etc,overlay,priv-app} -type d -exec chcon --reference=system/product/app {} \;
          ls gapps/etc/ | xargs -n 1 -I dir sudo find system/system/etc/dir -type d -exec chcon --reference=system/system/etc/permissions {} \;

          sudo find system/system/{app,framework,priv-app} -type f -exec chcon --reference=system/system/framework/ext.jar {} \;
          ls gapps/etc/ | xargs -n 1 -I dir sudo find system/system/etc/dir -type f -exec chcon --reference=system/system/etc/permissions {} \;
          sudo find system/product/{app,etc,overlay,priv-app} -type f -exec chcon --reference=system/product/etc/permissions/privapp-permissions-venezia.xml {} \;
          chmod +x ./magiskpolicy
          sudo ./magiskpolicy --load system/vendor/etc/selinux/precompiled_sepolicy --save system/vendor/etc/selinux/precompiled_sepolicy "allow gmscore_app gmscore_app vsock_socket { create connect write read }" "allow gmscore_app device_config_runtime_native_boot_prop file read" "allow gmscore_app system_server_tmpfs dir search" "allow gmscore_app system_server_tmpfs file open"
      - name: Fix GApps prop
        if: ${{ github.event.inputs.gapps_variant != 'none' && github.event.inputs.gapps_variant != '' }}
        shell: sudo python {0}
        run: |
          from __future__ import annotations
          from io import TextIOWrapper
          from os import system
          from typing import OrderedDict


          class Prop(OrderedDict):
              def __init__(self, file: TextIOWrapper) -> None:
                  super().__init__()
                  for i, line in enumerate(file.read().splitlines(False)):
                      if '=' in line:
                          k, v = line.split('=', 2)
                          self[k] = v
                      else:
                          self[f".{i}"] = line

              def __str__(self) -> str:
                  return '\n'.join([v if k.startswith('.') else f"{k}={v}" for k, v in self.items()])

              def __iadd__(self, other: str) -> Prop:
                  self[f".{len(self)}"] = other
                  return self


          new_props = {
              ("product", "brand"): "google",
              ("product", "manufacturer"): "Google",
              ("build", "product"): "redfin",
              ("product", "name"): "redfin",
              ("product", "device"): "redfin",
              ("product", "model"): "Pixel 5",
              ("build", "flavor"): "redfin-user"
          }


          def description(sec: str, p: Prop) -> str:
              return f"{p[f'ro.{sec}.build.flavor']} {p[f'ro.{sec}.build.version.release_or_codename']} {p[f'ro.{sec}.build.id']} {p[f'ro.{sec}.build.version.incremental']} {p[f'ro.{sec}.build.tags']}"


          def fingerprint(sec: str, p: Prop) -> str:
              return f"""{p[f"ro.product.{sec}.brand"]}/{p[f"ro.product.{sec}.name"]}/{p[f"ro.product.{sec}.device"]}:{p[f"ro.{sec}.build.version.release"]}/{p[f"ro.{sec}.build.id"]}/{p[f"ro.{sec}.build.version.incremental"]}:{p[f"ro.{sec}.build.type"]}/{p[f"ro.{sec}.build.tags"]}"""


          def fix_prop(sec, prop):
              print(f"fixing {prop}", flush=True)
              with open(prop, 'r') as f:
                  p = Prop(f)

              p += "# extra prop added by MagiskOnWSA"

              for k, v in new_props.items():
                  p[f"ro.{k[0]}.{k[1]}"] = v
                  
                  if k[0] == "build":
                      p[f"ro.{sec}.{k[0]}.{k[1]}"] = v
                  elif k[0] == "product":
                      p[f"ro.{k[0]}.{sec}.{k[1]}"] = v

              p["ro.build.description"] = description(sec, p)
              p[f"ro.build.fingerprint"] = fingerprint(sec, p)
              p[f"ro.{sec}.build.description"] = description(sec, p)
              p[f"ro.{sec}.build.fingerprint"] = fingerprint(sec, p)
              p[f"ro.bootimage.build.fingerprint"] = fingerprint(sec, p)

              with open(prop, 'w') as f:
                  f.write(str(p))

          for sec, prop in {"system": "system/system/build.prop", "product": "system/product/build.prop", "system_ext": "system/system_ext/build.prop", "vendor": "system/vendor/build.prop", "odm": "system/vendor/odm/etc/build.prop"}.items():
              fix_prop(sec, prop)
      - name: Umount images
        run: |
          sudo umount system/vendor
          sudo umount system/product
          sudo umount system/system_ext
          sudo umount system
          sudo umount userdata
          qemu-img convert -o subformat=dynamic -f raw -O vhdx userdata.img ${{ matrix.arch }}/userdata.vhdx
      - name: Shrink images
        run: |
          e2fsck -yf ${{ matrix.arch }}/system.img
          resize2fs -M ${{ matrix.arch }}/system.img
          e2fsck -yf ${{ matrix.arch }}/vendor.img
          resize2fs -M ${{ matrix.arch }}/vendor.img
          e2fsck -yf ${{ matrix.arch }}/product.img
          resize2fs -M ${{ matrix.arch }}/product.img
          e2fsck -yf ${{ matrix.arch }}/system_ext.img
          resize2fs -M ${{ matrix.arch }}/system_ext.img
      - name: Remove signature and add scripts
        run: |
          rm -rf ${{ matrix.arch }}/\[Content_Types\].xml ${{ matrix.arch }}/AppxBlockMap.xml ${{ matrix.arch }}/AppxSignature.p7x ${{ matrix.arch }}/AppxMetadata
          cp vclibs.appx xaml.appx ${{ matrix.arch }}
          tee ${{ matrix.arch }}/Install.ps1 <<EOF
          # Automated Install script by Mioki
          # http://github.com/okibcn
          function Test-Administrator {
              [OutputType([bool])]
              param()
              process {
                  [Security.Principal.WindowsPrincipal]\$user = [Security.Principal.WindowsIdentity]::GetCurrent();
                  return \$user.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator);
              }
          }

          function Finish {
              Clear-Host
              Start-Process "wsa://com.topjohnwu.magisk"
              Start-Process "wsa://com.android.vending"
          }

          if (-not (Test-Administrator)) {
              \$proc = Start-Process -PassThru -WindowStyle Hidden -Verb RunAs powershell.exe -Args "-executionpolicy bypass -command Set-Location \`"\$PSScriptRoot\`"; \`"\$PSCommandPath\`" EVAL"
              \$proc.WaitForExit()
              if (\$proc.ExitCode -ne 0) {
                  Clear-Host
                  Write-Warning "Failed to launch start as Administrator\`r\`nPress any key to exit"
                  \$null = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
              }
              exit
          }
          elseif ((\$args.Count -eq 1) -and (\$args[0] -eq "EVAL")) {
              Start-Process powershell.exe -Args "-executionpolicy bypass -command Set-Location \`"\$PSScriptRoot\`"; \`"\$PSCommandPath\`""
              exit
          }

          reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"

          \$VMP = Get-WindowsOptionalFeature -Online -FeatureName 'VirtualMachinePlatform'
          if (\$VMP.State -ne "Enabled") {
              Enable-WindowsOptionalFeature -Online -NoRestart -FeatureName 'VirtualMachinePlatform'
              Clear-Host
              Write-Warning "Need restart to enable virtual machine platform\`r\`nPress y to restart or press any key to exit"
              \$key = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
              If ("y" -eq \$key.Character) {
                  Restart-Computer -Confirm
              }
              Else {
                  exit 1
              }
          }

          Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Path vclibs.appx
          Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Path xaml.appx

          \$Installed = \$null
          \$Installed = Get-AppxPackage -Name 'MicrosoftCorporationII.WindowsSubsystemForAndroid'

          If ((\$null -ne \$Installed) -and (-not (\$Installed.IsDevelopmentMode))) {
              Clear-Host
              Write-Warning "There is already one installed WSA. Please uninstall it first.\`r\`nPress y to uninstall existing WSA or press any key to exit"
              \$key = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
              If ("y" -eq \$key.Character) {
                  Remove-AppxPackage -Package \$Installed.PackageFullName
              }
              Else {
                  exit 1
              }
          }
          Clear-Host
          Write-Host "Installing MagiskOnWSA..."
          Stop-Process -Name "wsaclient"
          Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Register .\AppxManifest.xml
          if (\$?) {
              Finish
          }
          Elseif (\$null -ne \$Installed) {
              Clear-Host
              Write-Host "Failed to update, try to uninstall existing installation while preserving userdata..."
              Remove-AppxPackage -PreserveApplicationData -Package \$Installed.PackageFullName
              Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Register .\AppxManifest.xml
              if (\$?) {
                  Finish
              }
          }
          Write-Host "All Done\`r\`nPress any key to exit"
          \$null = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
          EOF
      - name: Generate artifact name
        run: |
          variant="${{ github.event.inputs.gapps_variant }}"
          root="${{ github.event.inputs.root_sol }}"
          if [[ "$root" = "none" ]]; then
            name1=""
          elif [[ "$root" = "" ]]; then
            name1="-with-magisk"
          else
            name1="-with-${root}"
          fi
          if [[ "$variant" = "none" || "$variant" = "" ]]; then
            name2="-NoGApps"
          else
            name2="-GApps-${variant}"
          fi
          echo "artifact_name=WSA${name1}${name2}_${{ env.WSA_VER }}_${{ matrix.arch }}_${{ env.WSA_REL }}" >> $GITHUB_ENV
      - name: Upload WSA
        uses: actions/upload-artifact@v2
        with:
          name: ${{ env.artifact_name }}
          path: "./${{ matrix.arch }}/*"
