This commit is contained in:
Peter Njeim 2022-08-29 21:37:38 -03:00
parent 959033d7f5
commit 35566f81c3
7 changed files with 0 additions and 1469 deletions

View File

@ -1,727 +0,0 @@
name: Build WSA
on:
workflow_dispatch:
inputs:
arch:
description: "Build architecture"
required: true
default: "x64"
type: choice
options:
- x64
- arm64
- x64 & arm64
release_type:
description: "WSA release type"
required: true
default: "insider fast"
type: choice
options:
- retail
- release preview
- insider slow
- insider fast
magisk_apk:
description: "Magisk version"
required: true
default: "stable"
type: choice
options:
- stable
- beta
- canary
- debug
gapps_variant:
description: "Variants of GApps"
required: true
default: "pico"
type: choice
options:
- none
- super
- stock
- full
- mini
- micro
- nano
- pico
- tvstock
- tvmini
gapps_version:
description: "Android version of GApps"
required: true
default: "12.1"
type: choice
options:
- 11.0
- 12.1
remove_amazon:
description: "Remove Amazon AppStore"
required: true
default: "remove"
type: choice
options:
- keep
- remove
root_sol:
description: "Root solution"
required: true
default: "magisk"
type: choice
options:
- magisk
- none
permissions:
contents: write
jobs:
matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Generate build matrix
id: set-matrix
uses: actions/github-script@v6
with:
script: |
let matrix = {};
let arch = "${{ github.event.inputs.arch }}"
switch ( arch ) {
case "x64":
matrix.arch = ["x64"];
break;
case "arm64":
matrix.arch = ["arm64"];
break;
default:
matrix.arch = ["x64", "arm64"];
break;
}
core.setOutput("matrix",JSON.stringify(matrix));
build:
runs-on: ubuntu-20.04
needs: matrix
strategy:
matrix: ${{fromJson(needs.matrix.outputs.matrix)}}
steps:
- name: Dependencies
run: |
sudo apt-get update && sudo apt-get install setools lzip wine winetricks patchelf
wget -qO- "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/archive/$GITHUB_REF.tar.gz" | sudo tar --wildcards -zxvf- -C ~ --strip-component=2 '*/wine/*' '*/linker/*' '*/xml/*'
winetricks msxml6
- name: Download WSA
shell: python
run: |
import requests
from xml.dom import minidom
import html
import warnings
import re
import zipfile
import os
import urllib.request
from pathlib import Path
warnings.filterwarnings("ignore")
arch = "${{ matrix.arch }}"
release_type_map = {"retail": "Retail", "release preview": "RP", "insider slow": "WIS", "insider fast": "WIF"}
release_type = release_type_map["${{ github.event.inputs.release_type }}"] if "${{ github.event.inputs.release_type }}" != "" else "Retail"
cat_id = '858014f3-3934-4abe-8078-4aa193e74ca8'
with open(Path.home() / "GetCookie.xml", "r") as f:
cookie_content = f.read()
out = requests.post(
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
data=cookie_content,
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
verify=False
)
doc = minidom.parseString(out.text)
cookie = doc.getElementsByTagName('EncryptedData')[0].firstChild.nodeValue
print(cookie)
with open(Path.home() / "WUIDRequest.xml", "r") as f:
cat_id_content = f.read().format(cookie, cat_id, release_type)
out = requests.post(
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
data=cat_id_content,
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
verify=False
)
doc = minidom.parseString(html.unescape(out.text))
filenames = {}
for node in doc.getElementsByTagName('Files'):
filenames[node.parentNode.parentNode.getElementsByTagName('ID')[0].firstChild.nodeValue] = f"{node.firstChild.attributes['InstallerSpecificIdentifier'].value}_{node.firstChild.attributes['FileName'].value}"
pass
identities = []
for node in doc.getElementsByTagName('SecuredFragment'):
filename = filenames[node.parentNode.parentNode.parentNode.getElementsByTagName('ID')[0].firstChild.nodeValue]
update_identity = node.parentNode.parentNode.firstChild
identities += [(update_identity.attributes['UpdateID'].value, update_identity.attributes['RevisionNumber'].value, filename)]
with open(Path.home() / "FE3FileUrl.xml", "r") as f:
file_content = f.read()
for i, v, f in identities:
if re.match(f"Microsoft\.UI\.Xaml\..*_{arch}_.*\.appx", f):
out_file = "xaml.appx"
elif re.match(f"Microsoft\.VCLibs\..*_{arch}_.*\.appx", f):
out_file = "vclibs.appx"
elif re.match(f"MicrosoftCorporationII\.WindowsSubsystemForAndroid_.*\.msixbundle", f):
out_file = "wsa.zip"
else:
continue
out = requests.post(
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured',
data=file_content.format(i, v, release_type),
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
verify=False
)
doc = minidom.parseString(out.text)
for l in doc.getElementsByTagName("FileLocation"):
url = l.getElementsByTagName("Url")[0].firstChild.nodeValue
if len(url) != 99:
if not os.path.isfile(out_file):
print(f"downloading link: {url} to {out_file}", flush=True)
urllib.request.urlretrieve(url, out_file)
zip_name = ""
with zipfile.ZipFile("wsa.zip") 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("_")
long_ver = ver_no[1]
ver=long_ver.split(".")
main_ver=ver[0]
with open(os.environ['GITHUB_ENV'], 'a') as g:
g.write(f'WSA_VER={long_ver}\n')
with open(os.environ['GITHUB_ENV'], 'a') as g:
g.write(f'WSA_MAIN_VER={main_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
import json
import requests
magisk_apk = """${{ github.event.inputs.magisk_apk }}"""
if not magisk_apk:
magisk_apk = "stable"
if magisk_apk == "stable" or magisk_apk == "beta" or magisk_apk == "canary" or magisk_apk == "debug":
magisk_apk = json.loads(requests.get(f"https://github.com/topjohnwu/magisk-files/raw/master/{magisk_apk}.json").content)['magisk']['link']
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")
standalone_policy = False
try:
zip.getinfo(f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so")
standalone_policy = True
except:
pass
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskinit", "magisk")
if standalone_policy:
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so", "magiskpolicy", "magisk")
else:
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")
if standalone_policy:
extract_as(zip, f"lib/{ abi_map['x64'][0] }/libmagiskpolicy.so", "magiskpolicy", ".")
else:
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 os
import urllib.request
import json
import re
arch = "${{ matrix.arch }}"
variant = "${{ github.event.inputs.gapps_variant }}"
abi_map = {"x64" : "x86_64", "arm64": "arm64"}
release = "${{ github.event.inputs.gapps_version }}"
if release == "12.1" and arch == "x64" and variant == "pico":
link = "http://peternjeim.ddns.net:8081/ipfs/QmPDiAyqUvZHo9QU7WfoEE9XMqC8ppGyUsSwKQY7chfwHX"
elif release == "12.1" and arch == "x64" and variant == "full":
link = "http://peternjeim.ddns.net:8081/ipfs/QmULfSMwWuukQR7r9KEvwD2XzsChHTvpswmNqJyEU64jwM"
else:
try:
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"][release]["variants"]}[variant]["zip"]
except Exception:
print("Failed to fetch from opengapps api, fallbacking to sourceforge rss...")
res = requests.get(f'https://sourceforge.net/projects/opengapps/rss?path=/{abi_map[arch]}&limit=100')
link = re.search(f'https://.*{abi_map[arch]}/.*{release}.*{variant}.*\.zip/download', res.text).group().replace('.zip/download', '.zip').replace('sourceforge.net/projects/opengapps/files', 'downloads.sourceforge.net/project/opengapps')
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
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'
- name: Expand images
run: |
e2fsck -yf ${{ matrix.arch }}/system_ext.img
system_ext_size=$(( $(du -sB512 ${{ matrix.arch }}/system_ext.img | cut -f1) + 20000 ))
resize2fs ${{ matrix.arch }}/system_ext.img "$system_ext_size"s
e2fsck -yf ${{ matrix.arch }}/product.img
product_size=$(( $(du -sB512 ${{ matrix.arch }}/product.img | cut -f1) + 20000 ))
if [ -d gapps/product ]; then
product_size=$(( $product_size + $(du -sB512 gapps/product | cut -f1) ))
fi
resize2fs ${{ matrix.arch }}/product.img "$product_size"s
e2fsck -yf ${{ matrix.arch }}/system.img
system_size=$(( $(du -sB512 ${{ matrix.arch }}/system.img | cut -f1) + 20000 ))
if [ -d gapps ]; then
system_size=$(( $system_size + $(du -sB512 gapps | cut -f1) - $(du -sB512 gapps/product | cut -f1) ))
fi
if [ -d magisk ]; then
system_size=$(( $system_size +$(du -sB512 magisk | cut -f1) ))
fi
if [ -f magisk.zip ]; then
system_size=$(( $system_size +$(du -sB512 magisk.zip | cut -f1) ))
fi
resize2fs ${{ matrix.arch }}/system.img "$system_size"s
e2fsck -yf ${{ matrix.arch }}/vendor.img
vendor_size=$(( $(du -sB512 ${{ matrix.arch }}/vendor.img | cut -f1) + 20000 ))
resize2fs ${{ matrix.arch }}/vendor.img "$vendor_size"s
- name: Mount images
run: |
sudo mkdir system
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
- name: Remove Amazon AppStore
if: ${{ github.event.inputs.remove_amazon == 'remove' }}
run: |
find system/product/{etc/permissions,etc/sysconfig,framework,priv-app} | grep -e amazon -e venezia | sudo xargs rm -rf
- 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 cp magisk.zip system/sbin/magisk.apk
sudo tee -a system/sbin/loadpolicy.sh <<EOF
#!/system/bin/sh
mkdir -p /data/adb/magisk
cp /sbin/* /data/adb/magisk/
chmod -R 755 /data/adb/magisk
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 {} \;
sudo patchelf --replace-needed libc.so "${HOME}/libc.so" ./magiskpolicy || true
sudo patchelf --replace-needed libm.so "${HOME}/libm.so" ./magiskpolicy || true
sudo patchelf --replace-needed libdl.so "${HOME}/libdl.so" ./magiskpolicy || true
sudo patchelf --set-interpreter "${HOME}/linker64" ./magiskpolicy || true
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
copy /sbin/magiskpolicy /dev/wsa-magisk/magiskpolicy
chmod 0755 /dev/wsa-magisk/magiskpolicy
mkdir /dev/wsa-magisk/.magisk 700
mkdir /dev/wsa-magisk/.magisk/mirror 700
mkdir /dev/wsa-magisk/.magisk/block 700
copy /sbin/magisk.apk /dev/wsa-magisk/stub.apk
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
mkdir /data/adb/magisk 755
copy /sbin/magisk.apk /data/adb/magisk/magisk.apk
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/com.android.settings.intelligence.xml {} \;
sudo patchelf --replace-needed libc.so "${HOME}/libc.so" ./magiskpolicy || true
sudo patchelf --replace-needed libm.so "${HOME}/libm.so" ./magiskpolicy || true
sudo patchelf --replace-needed libdl.so "${HOME}/libdl.so" ./magiskpolicy || true
sudo patchelf --set-interpreter "${HOME}/linker64" ./magiskpolicy || true
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, path
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):
if not path.exists(prop):
return
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 find system -exec touch -amt 200901010000.00 {} \;> /dev/null 2>&1
sudo umount system/vendor
sudo umount system/product
sudo umount system/system_ext
sudo umount system
- 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)) {
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
\$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
}
if (((Test-Path -Path $(ls -Q ./${{ matrix.arch }} | paste -sd "," -)) -eq \$false).Count) {
Write-Error "Some files are missing in the zip. Please try to download it again from the browser downloader, or try to run the workflow again. Press any key to exist"
\$null = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
exit 1
}
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" -ErrorAction "silentlycontinue"
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 release asset name
run: |
variant="${{ github.event.inputs.gapps_variant }}"
root="${{ github.event.inputs.root_sol }}"
magisk="${{ github.event.inputs.magisk_apk }}"
amazon="${{ github.event.inputs.remove_amazon }}"
if [[ "$root" = "none" ]]; then
rootVer=""
elif [[ "$root" = "" ]]; then
rootVer="_Magisk-$(curl -s https://raw.githubusercontent.com/topjohnwu/magisk-files/master/$magisk.json | jq -r ".magisk.version")"
else
rootVer="_Magisk-$(curl -s https://raw.githubusercontent.com/topjohnwu/magisk-files/master/$magisk.json | jq -r ".magisk.version")"
fi
if [[ "$variant" = "none" || "$variant" = "" ]]; then
gappsVer=""
else
gappsVer="_${variant}-GApps"
fi
if [[ "$amazon" == "remove" ]]; then
amazonVer=""
else
amazonVer="_Amazon-App-Store"
fi
echo "release_asset_name=WSA_${{ env.WSA_VER }}$rootVer$gappsVer$amazonVer_${{ matrix.arch }}" >> $GITHUB_ENV
- name: Compress
run: |
zip -qrv "${{ env.release_asset_name }}.zip" ./${{ matrix.arch }}/*
- name: Upload WSA
uses: softprops/action-gh-release@v1
with:
files: ./${{ env.release_asset_name }}.zip
tag_name: WSA

View File

@ -1,742 +0,0 @@
name: Build WSA New
on:
workflow_dispatch:
inputs:
arch:
description: "Build architecture"
required: true
default: "x64"
type: choice
options:
- x64
- arm64
- x64 & arm64
release_type:
description: "WSA release type"
required: true
default: "insider fast"
type: choice
options:
- retail
- release preview
- insider slow
- insider fast
magisk_apk:
description: "Magisk version"
required: true
default: "stable"
type: choice
options:
- stable
- beta
- canary
- debug
gapps_variant:
description: "GApps variant"
required: true
default: "pico"
type: choice
options:
- none
- full
- pico
remove_amazon:
description: "Remove Amazon Appstore"
required: true
default: "remove"
type: choice
options:
- keep
- remove
root_sol:
description: "Install Magisk"
required: true
default: "magisk"
type: choice
options:
- magisk
- none
permissions:
contents: write
jobs:
matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Generate build matrix
id: set-matrix
uses: actions/github-script@v6
with:
script: |
let matrix = {};
let arch = "${{ github.event.inputs.arch }}"
switch ( arch ) {
case "x64":
matrix.arch = ["x64"];
break;
case "arm64":
matrix.arch = ["arm64"];
break;
default:
matrix.arch = ["x64", "arm64"];
break;
}
core.setOutput("matrix",JSON.stringify(matrix));
build:
runs-on: ubuntu-20.04
needs: matrix
strategy:
matrix: ${{fromJson(needs.matrix.outputs.matrix)}}
steps:
- name: Dependencies
run: |
sudo apt-get update && sudo apt-get install setools lzip wine winetricks patchelf e2fsprogs aria2
wget -qO- "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/archive/$GITHUB_REF.tar.gz" | sudo tar --wildcards -zxvf- -C ~ --strip-component=2 '*/wine/*' '*/linker/*' '*/xml/*'
winetricks msxml6
- name: Generate download links
shell: python
run: |
import requests
from xml.dom import minidom
import html
import re
import zipfile
import os
import json
import re
from pathlib import Path
arch = "${{ matrix.arch }}"
release_type_map = {"retail": "Retail", "release preview": "RP", "insider slow": "WIS", "insider fast": "WIF"}
release_type = release_type_map["${{ github.event.inputs.release_type }}"] if "${{ github.event.inputs.release_type }}" != "" else "Retail"
cat_id = '858014f3-3934-4abe-8078-4aa193e74ca8'
print(f"Generating WSA download link: arch={arch} release_type={release_type}", flush=True)
with open(Path.home() / "GetCookie.xml", "r") as f:
cookie_content = f.read()
out = requests.post(
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
data=cookie_content,
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
verify=False
)
doc = minidom.parseString(out.text)
cookie = doc.getElementsByTagName('EncryptedData')[0].firstChild.nodeValue
with open(Path.home() / "WUIDRequest.xml", "r") as f:
cat_id_content = f.read().format(cookie, cat_id, release_type)
out = requests.post(
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
data=cat_id_content,
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
verify=False
)
doc = minidom.parseString(html.unescape(out.text))
filenames = {}
for node in doc.getElementsByTagName('Files'):
filenames[node.parentNode.parentNode.getElementsByTagName('ID')[0].firstChild.nodeValue] = f"{node.firstChild.attributes['InstallerSpecificIdentifier'].value}_{node.firstChild.attributes['FileName'].value}"
pass
identities = []
for node in doc.getElementsByTagName('SecuredFragment'):
filename = filenames[node.parentNode.parentNode.parentNode.getElementsByTagName('ID')[0].firstChild.nodeValue]
update_identity = node.parentNode.parentNode.firstChild
identities += [(update_identity.attributes['UpdateID'].value, update_identity.attributes['RevisionNumber'].value, filename)]
with open(Path.home() / "FE3FileUrl.xml", "r") as f:
file_content = f.read()
tmpdownlist = open("download.list", 'a')
for i, v, f in identities:
if re.match(f"Microsoft\.UI\.Xaml\..*_{arch}_.*\.appx", f):
out_file = "xaml.appx"
elif re.match(f"MicrosoftCorporationII\.WindowsSubsystemForAndroid_.*\.msixbundle", f):
out_file = "wsa.zip"
else:
continue
out = requests.post(
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured',
data=file_content.format(i, v, release_type),
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
verify=False
)
doc = minidom.parseString(out.text)
for l in doc.getElementsByTagName("FileLocation"):
url = l.getElementsByTagName("Url")[0].firstChild.nodeValue
if len(url) != 99:
print(f"download link: {url} to {out_file}", flush=True)
tmpdownlist.writelines(url + '\n')
tmpdownlist.writelines(f' dir=.\n')
tmpdownlist.writelines(f' out={out_file}\n')
tmpdownlist.writelines(f'https://aka.ms/Microsoft.VCLibs.{arch}.14.00.Desktop.appx\n')
tmpdownlist.writelines(f' dir=.\n')
tmpdownlist.writelines(f' out=vclibs.appx\n')
tmpdownlist.close
magisk_ver = """${{ github.event.inputs.magisk_ver }}"""
print(f"Generating Magisk download link: release type={magisk_ver}", flush=True)
if not magisk_ver:
magisk_ver = "stable"
if magisk_ver == "stable" or magisk_ver == "beta" or magisk_ver == "canary" or magisk_ver == "debug":
magisk_ver = json.loads(requests.get(f"https://github.com/topjohnwu/magisk-files/raw/master/{magisk_ver}.json").content)['magisk']['link']
print(f"download link: {magisk_ver}", flush=True)
out_file = "magisk.zip"
with open("download.list", 'a') as f:
f.writelines(f'{magisk_ver}\n')
f.writelines(f' dir=.\n')
f.writelines(f' out=magisk.zip\n')
variant = "${{ github.event.inputs.gapps_variant }}"
if variant != "none" and variant != "":
print(f"Generating OpenGapps download link: arch={arch} variant={variant}", flush=True)
abi_map = {"x64": "x86_64", "arm64": "arm64"}
if arch == "x64" and variant == "pico":
link = "http://peternjeim.ddns.net:8081/ipfs/QmPDiAyqUvZHo9QU7WfoEE9XMqC8ppGyUsSwKQY7chfwHX"
elif arch == "x64" and variant == "full":
link = "http://peternjeim.ddns.net:8081/ipfs/QmULfSMwWuukQR7r9KEvwD2XzsChHTvpswmNqJyEU64jwM"
else:
variant = "pico"
print("only pico gapps variant is supported on arm64", flush=True)
try:
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"]
except Exception:
print("Failed to fetch from opengapps api, fallbacking to sourceforge rss...")
res = requests.get(f'https://sourceforge.net/projects/opengapps/rss?path=/{abi_map[arch]}&limit=100')
link = re.search(f'https://.*{abi_map[arch]}/.11.0.*{variant}.*\.zip/download', res.text).group().replace('.zip/download', '.zip').replace('sourceforge.net/projects/opengapps/files', 'downloads.sourceforge.net/project/opengapps')
print(f"download link: {link}", flush=True)
with open("download.list", 'a') as f:
f.writelines(f'{link}\n')
f.writelines(f' dir=.\n')
f.writelines(f' out=gapps.zip\n')
f.close
- name: Download artifacts
run: |
if ! aria2c --no-conf --log-level=info --log="./aria2_download.log" -x16 -s16 -j5 -c -R -m0 -i"download.list"; then
echo "We have encountered an error while downloading files."
exit 1
fi
- name: Extract WSA
shell: python
run: |
import warnings
import zipfile
import os
warnings.filterwarnings("ignore")
arch = "${{ matrix.arch }}"
zip_name = ""
with zipfile.ZipFile("wsa.zip") 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("_")
long_ver = ver_no[1]
ver = long_ver.split(".")
main_ver = ver[0]
with open(os.environ['GITHUB_ENV'], 'a') as g:
g.write(f'WSA_VER={long_ver}\n')
with open(os.environ['GITHUB_ENV'], 'a') as g:
g.write(f'WSA_MAIN_VER={main_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: Extract Magisk
shell: python
run: |
import zipfile
import os
magisk_zip = "magisk.zip"
arch = "${{ matrix.arch }}"
abi_map = {"x64": ["x86_64", "x86"], "arm64": ["arm64-v8a", "armeabi-v7a"]}
def extract_as(zip, name, as_name, dir):
info = zip.getinfo(name)
info.filename = as_name
zip.extract(info, dir)
with zipfile.ZipFile(magisk_zip) 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")
standalone_policy = False
try:
zip.getinfo(f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so")
standalone_policy = True
except:
pass
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskinit", "magisk")
if standalone_policy:
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so", "magiskpolicy", "magisk")
else:
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")
if standalone_policy:
extract_as(zip, f"lib/{ abi_map['x64'][0] }/libmagiskpolicy.so", "magiskpolicy", ".")
else:
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: Extract GApps
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 -xf - -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'
- name: Expand images
run: |
e2fsck -yf ${{ matrix.arch }}/system_ext.img
SYSTEM_EXT_SIZE=$(($(du --apparent-size -sB512 ${{ matrix.arch }}/system_ext.img | cut -f1) + 20000))
if [ -d gapps/system_ext ]; then
SYSTEM_EXT_SIZE=$(( SYSTEM_EXT_SIZE + $(du --apparent-size -sB512 gapps/system_ext | cut -f1) ))
fi
resize2fs ${{ matrix.arch }}/system_ext.img "$SYSTEM_EXT_SIZE"s
e2fsck -yf ${{ matrix.arch }}/product.img
PRODUCT_SIZE=$(($(du --apparent-size -sB512 ${{ matrix.arch }}/product.img | cut -f1) + 20000))
if [ -d gapps/product ]; then
PRODUCT_SIZE=$(( $PRODUCT_SIZE + $(du --apparent-size -sB512 gapps/product | cut -f1) ))
fi
resize2fs ${{ matrix.arch }}/product.img "$PRODUCT_SIZE"s
e2fsck -yf ${{ matrix.arch }}/system.img
SYSTEM_SIZE=$(($(du --apparent-size -sB512 ${{ matrix.arch }}/system.img | cut -f1) + 20000))
if [ -d gapps ]; then
SYSTEM_SIZE=$(( $SYSTEM_SIZE + $(du --apparent-size -sB512 gapps | cut -f1) - $(du --apparent-size -sB512 gapps/product | cut -f1) ))
if [ -d gapps/system_ext ]; then
SYSTEM_SIZE=$(( $SYSTEM_SIZE - $(du --apparent-size -sB512 gapps/system_ext | cut -f1) ))
fi
fi
if [ -d magisk ]; then
SYSTEM_SIZE=$(( $SYSTEM_SIZE +$(du --apparent-size -sB512 magisk | cut -f1) ))
fi
if [ -f magisk.zip ]; then
SYSTEM_SIZE=$(( $SYSTEM_SIZE +$(du --apparent-size -sB512 magisk.zip | cut -f1) ))
fi
if [ -d system ]; then
SYSTEM_SIZE=$(( $SYSTEM_SIZE +$(du --apparent-size -sB512 system | cut -f1) ))
fi
resize2fs ${{ matrix.arch }}/system.img "$SYSTEM_SIZE"s
e2fsck -yf ${{ matrix.arch }}/vendor.img
VENDOR_SIZE=$(($(du --apparent-size -sB512 ${{ matrix.arch }}/vendor.img | cut -f1) + 20000))
resize2fs ${{ matrix.arch }}/vendor.img "$VENDOR_SIZE"s
- name: Mount images
run: |
sudo mkdir system
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
- name: Remove Amazon AppStore
if: ${{ github.event.inputs.remove_amazon == 'remove' }}
run: |
find system/product/{etc/permissions,etc/sysconfig,framework,priv-app} | grep -e amazon -e venezia | sudo xargs rm -rf
- 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 cp magisk.zip system/sbin/magisk.apk
sudo tee -a system/sbin/loadpolicy.sh <<EOF
#!/system/bin/sh
mkdir -p /data/adb/magisk
cp /sbin/* /data/adb/magisk/
chmod -R 755 /data/adb/magisk
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 {} \;
sudo patchelf --replace-needed libc.so "${HOME}/libc.so" ./magiskpolicy || true
sudo patchelf --replace-needed libm.so "${HOME}/libm.so" ./magiskpolicy || true
sudo patchelf --replace-needed libdl.so "${HOME}/libdl.so" ./magiskpolicy || true
sudo patchelf --set-interpreter "${HOME}/linker64" ./magiskpolicy || true
chmod +x ./magiskpolicy
TMP_PATH=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c8)
echo "/dev/$TMP_PATH(/.*)? 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 *"
SERVER_NAME1=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c12)
SERVER_NAME2=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c12)
SERVER_NAME3=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c12)
SERVER_NAME4=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c12)
sudo tee -a system/system/etc/init/hw/init.rc <<EOF
on post-fs-data
start adbd
mkdir /dev/$TMP_PATH
mount tmpfs tmpfs /dev/$TMP_PATH mode=0755
copy /sbin/magisk64 /dev/$TMP_PATH/magisk64
chmod 0755 /dev/$TMP_PATH/magisk64
symlink ./magisk64 /dev/$TMP_PATH/magisk
symlink ./magisk64 /dev/$TMP_PATH/su
symlink ./magisk64 /dev/$TMP_PATH/resetprop
copy /sbin/magisk32 /dev/$TMP_PATH/magisk32
chmod 0755 /dev/$TMP_PATH/magisk32
copy /sbin/magiskinit /dev/$TMP_PATH/magiskinit
chmod 0755 /dev/$TMP_PATH/magiskinit
copy /sbin/magiskpolicy /dev/$TMP_PATH/magiskpolicy
chmod 0755 /dev/$TMP_PATH/magiskpolicy
mkdir /dev/$TMP_PATH/.magisk 700
mkdir /dev/$TMP_PATH/.magisk/mirror 700
mkdir /dev/$TMP_PATH/.magisk/block 700
copy /sbin/magisk.apk /dev/$TMP_PATH/stub.apk
rm /dev/.magisk_unblock
start $SERVER_NAME1
start $SERVER_NAME2
wait /dev/.magisk_unblock 40
rm /dev/.magisk_unblock
service $SERVER_NAME1 /system/bin/sh /sbin/loadpolicy.sh
user root
seclabel u:r:magisk:s0
oneshot
service $SERVER_NAME2 /dev/$TMP_PATH/magisk --post-fs-data
user root
seclabel u:r:magisk:s0
oneshot
service $SERVER_NAME3 /dev/$TMP_PATH/magisk --service
class late_start
user root
seclabel u:r:magisk:s0
oneshot
on property:sys.boot_completed=1
mkdir /data/adb/magisk 755
copy /sbin/magisk.apk /data/adb/magisk/magisk.apk
start $SERVER_NAME4
service $SERVER_NAME4 /dev/$TMP_PATH/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/*'
find system/system/priv-app/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I dir sudo find system/system/priv-app/dir -type d -exec chmod 0755 {} \;
find system/system/priv-app/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I dir sudo find system/system/priv-app/dir -type f -exec chmod 0644 {} \;
find system/system/priv-app/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I dir sudo find system/system/priv-app/dir -exec chown root:root {} \;
find system/system/priv-app/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I dir sudo find system/system/priv-app/dir -exec chcon --reference=system/system/priv-app {} \;
find system/system/etc/permissions/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I file sudo find system/system/etc/permissions/file -type f -exec chmod 0644 {} \;
find system/system/etc/permissions/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I file sudo find system/system/etc/permissions/file -exec chown root:root {} \;
find system/system/etc/permissions/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I file sudo find system/system/etc/permissions/file -type f -exec chcon --reference=system/system/etc/permissions/platform.xml {} \;
- name: Integrate GApps
if: ${{ github.event.inputs.gapps_variant != 'none' && github.event.inputs.gapps_variant != '' }}
run: |
find "gapps/" -mindepth 1 -type d -exec sudo chmod 0755 {} \;
find "gapps/" -mindepth 1 -type d -exec sudo chown root:root {} \;
file_list="$(find "gapps/" -mindepth 1 -type f | cut -d/ -f5-)"
for file in $file_list; do
sudo chown root:root "gapps/${file}"
sudo chmod 0644 "gapps/${file}"
done
find gapps/ -maxdepth 1 -mindepth 1 -type d -not -path '*product' -exec sudo cp --preserve=all -r {} system \; || abort
sudo cp --preserve=all -r gapps/product/* product || abort
find gapps/product/overlay -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I file sudo find product/overlay/file -type f -exec chcon --reference=product/overlay/FontNotoSerifSource/FontNotoSerifSourceOverlay.apk {} \;
find gapps/app/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I dir sudo find system/app/dir -type d -exec chcon --reference=system/app {} \;
find gapps/framework/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I dir sudo find system/framework/dir -type d -exec chcon --reference=system/framework {} \;
find gapps/priv-app/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I dir sudo find system/priv-app/dir -type d -exec chcon --reference=system/priv-app {} \;
find gapps/app/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I file sudo find system/app/file -type f -exec chcon --reference=system/app/KeyChain/KeyChain.apk {} \;
find gapps/framework/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I file sudo find system/framework/file -type f -exec chcon --reference=system/framework/ext.jar {} \;
find gapps/priv-app/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I file sudo find system/priv-app/file -type f -exec chcon --reference=system/priv-app/Shell/Shell.apk {} \;
find gapps/etc/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I dir sudo find system/etc/dir -type d -exec chcon --reference=system/etc/permissions {} \;
find gapps/etc/ -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I dir sudo find system/etc/dir -type f -exec chcon --reference=system/etc/permissions {} \;
sudo patchelf --replace-needed libc.so "${HOME}/libc.so" ./magiskpolicy || true
sudo patchelf --replace-needed libm.so "${HOME}/libm.so" ./magiskpolicy || true
sudo patchelf --replace-needed libdl.so "${HOME}/libdl.so" ./magiskpolicy || true
sudo patchelf --set-interpreter "${HOME}/linker64" ./magiskpolicy || true
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, path
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):
if not path.exists(prop):
return
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 find system -exec touch -amt 200901010000.00 {} \;> /dev/null 2>&1
sudo umount system/vendor
sudo umount system/product
sudo umount system/system_ext
sudo umount system
- 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 Midonei
# http://github.com/doneibcn
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)) {
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
\$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
}
if (((Test-Path -Path $(find ./${{ matrix.arch }} -maxdepth 1 -mindepth 1 -printf "\"%P\"\n | paste -sd "," -)) -eq \$false).Count) {
Write-Error "Some files are missing in the folder. Please try to download the Release from GitHub again. Press any key to exit"
\$null = \$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
exit 1
}
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" -ErrorAction "silentlycontinue"
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 release asset name
run: |
variant="${{ github.event.inputs.gapps_variant }}"
root="${{ github.event.inputs.root_sol }}"
magisk="${{ github.event.inputs.magisk_apk }}"
amazon="${{ github.event.inputs.remove_amazon }}"
if [[ "$root" = "none" ]]; then
rootVer=""
elif [[ "$root" = "" ]]; then
rootVer="_Magisk-$(curl -s https://raw.githubusercontent.com/topjohnwu/magisk-files/master/$magisk.json | jq -r ".magisk.version")"
else
rootVer="_Magisk-$(curl -s https://raw.githubusercontent.com/topjohnwu/magisk-files/master/$magisk.json | jq -r ".magisk.version")"
fi
if [[ "$variant" = "none" || "$variant" = "" ]]; then
gappsVer=""
else
gappsVer="_${variant}-GApps"
fi
if [[ "$amazon" == "remove" ]]; then
amazonVer=""
else
amazonVer="_Amazon-App-Store"
fi
echo "release_asset_name=WSA_${{ env.WSA_VER }}$rootVer$gappsVer$amazonVer_${{ matrix.arch }}" >> $GITHUB_ENV
- name: Compress
run: |
zip -qrv "${{ env.release_asset_name }}.zip" ./${{ matrix.arch }}/*
- name: Upload WSA
uses: softprops/action-gh-release@v1
with:
files: ./${{ env.release_asset_name }}.zip
tag_name: WSA

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.