diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml deleted file mode 100644 index 65dc253..0000000 --- a/.github/workflows/build-and-release.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Compile and Release - -on: - push: - tags: - - '*' - workflow_dispatch: - inputs: - tag: - description: 'Tag for the release (e.g. v1.0.0)' - required: true - -# Add permissions to fix the 403 Forbidden error -permissions: - contents: write - packages: read - -jobs: - build: - runs-on: windows-latest - env: - RELEASE_TAG: ${{ github.event.inputs.tag || github.ref_name }} - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - # Add caching for faster builds - - name: Cache MinGW - uses: actions/cache@v4 - id: cache - with: - path: C:\winlibs - key: ${{ runner.os }}-mingw-14.2.0 - - - name: Download winlibs (GCC 14.1.0) - if: steps.cache.outputs.cache-hit != 'true' - run: | - Invoke-WebRequest -Uri "https://github.com/brechtsanders/winlibs_mingw/releases/download/14.2.0posix-19.1.7-12.0.0-msvcrt-r3/winlibs-x86_64-posix-seh-gcc-14.2.0-mingw-w64msvcrt-12.0.0-r3.zip" -OutFile winlibs.zip - 7z x winlibs.zip -oC:\winlibs - - - name: Add winlibs to PATH - run: echo "C:\winlibs\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - # Add optimization flags to the compilation - - name: Compile C++ file with optimizations - run: g++ Magisk.cpp -o magisk.exe -O3 -s -DNDEBUG - - # Improved Create Release step - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 - with: - tag_name: ${{ env.RELEASE_TAG }} - name: "BlueStacks Root ${{ env.RELEASE_TAG }}" - body: | - BlueStacks Root Tool Release ${{ env.RELEASE_TAG }} - - ## Files: - - `magisk.exe`: Compiled binary for rooting BlueStacks - - `NewblueStacksRoot.cmd`: Optimized script for rooting BlueStacks - files: | - magisk.exe - NewblueStacksRoot.cmd - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..989bec0 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,49 @@ +name: tests + +# Runs the PowerShell unit/integration tests on Windows and verifies the single-file build is in +# sync. No compiling, no auto-releasing -- releases are cut by hand. Replaces the old +# "Compile and Release" workflow, which built a since-deleted Magisk.cpp and could clobber releases. + +on: + push: + branches: [ main ] + paths-ignore: + - '**.md' + - 'docs/**' + - 'archive/**' + - 'recovered/**' + - 'LICENSE' + pull_request: + branches: [ main ] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: tests-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Windows PowerShell tests + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + + # The .cmd ships the engine + orchestrator embedded; make sure they match tools\*.ps1. + - name: Embedded build in sync with tools/ + shell: cmd + run: powershell -NoProfile -ExecutionPolicy Bypass -File tests\Check-Embedded-Sync.ps1 + + # Core engine: integrity patch, .bstk disk-mode, conf root flags, su round-trip, bootstrap. + # (Invoked via powershell.exe -File exactly as blueStackRoot.cmd does, i.e. Windows PowerShell 5.1.) + - name: Engine unit / integration tests + shell: cmd + run: powershell -NoProfile -ExecutionPolicy Bypass -File tests\Run-Tests.ps1 + + # Nothing-hardcoded guarantees: custom install/data paths + adb port (5555 is not assumed). + - name: Path + adb-port resolution tests + shell: cmd + run: powershell -NoProfile -ExecutionPolicy Bypass -File tests\Run-Resolve-Tests.ps1 diff --git a/tests/Check-Embedded-Sync.ps1 b/tests/Check-Embedded-Sync.ps1 new file mode 100644 index 0000000..3f26983 --- /dev/null +++ b/tests/Check-Embedded-Sync.ps1 @@ -0,0 +1,46 @@ +<# + Check-Embedded-Sync.ps1 -- CI guard for the single-file build. + + blueStackRoot.cmd carries the engine and the Magisk orchestrator embedded between marker lines. + They are authored in tools\bsr_engine.ps1 / tools\bsr_magisk.ps1 and spliced in by tools\reembed.ps1. + If someone edits a tools\*.ps1 without re-running reembed, the .cmd silently ships stale logic. + + This test extracts the embedded blocks exactly like the .cmd does at run time and compares them to + the tools\ sources (newline-normalised). Exit code 1 on any drift, 0 when in sync. + + Usage: powershell -NoProfile -ExecutionPolicy Bypass -File tests\Check-Embedded-Sync.ps1 +#> +$ErrorActionPreference = 'Stop' +$here = if ($PSScriptRoot) { $PSScriptRoot } elseif ($PSCommandPath) { Split-Path -Parent $PSCommandPath } else { (Get-Location).Path } +$repo = Split-Path -Parent $here +$cmd = Join-Path $repo 'blueStackRoot.cmd' +if (-not (Test-Path -LiteralPath $cmd)) { throw "blueStackRoot.cmd not found: $cmd" } +$t = [IO.File]::ReadAllText($cmd) + +function Norm([string]$s) { ($s -replace "`r`n", "`n").TrimEnd("`n", " ", "`t") } +function Extract([string]$tag) { + $b = '__BSR_' + $tag + '_' + 'BEGIN__'; $e = '__BSR_' + $tag + '_' + 'END__' + $i = $t.IndexOf($b); $j = $t.IndexOf($e) + if ($i -lt 0 -or $j -le $i) { throw "embedded block $tag not found in blueStackRoot.cmd" } + $i = $t.IndexOf([char]10, $i) + 1 + return $t.Substring($i, $j - $i) +} + +$fail = 0 +foreach ($p in @(@('ENGINE', 'tools\bsr_engine.ps1'), @('MAGISK', 'tools\bsr_magisk.ps1'))) { + $src = Join-Path $repo $p[1] + if (-not (Test-Path -LiteralPath $src)) { Write-Host " [FAIL] source missing: $($p[1])" -ForegroundColor Red; $fail++; continue } + $emb = Norm (Extract $p[0]) + $on = Norm ([IO.File]::ReadAllText($src)) + if ($emb -eq $on) { + Write-Host (" [PASS] {0,-7} embedded == {1} ({2} chars)" -f $p[0], $p[1], $emb.Length) -ForegroundColor Green + } else { + Write-Host (" [FAIL] {0,-7} embedded != {1} (embedded {2}, source {3} chars) -- run tools\reembed.ps1" -f $p[0], $p[1], $emb.Length, $on.Length) -ForegroundColor Red + $fail++ + } +} + +Write-Host "" +if ($fail) { Write-Host "RESULT: embedded blocks OUT OF SYNC ($fail) -- re-run tools\reembed.ps1 and commit blueStackRoot.cmd" -ForegroundColor Red; exit 1 } +Write-Host "RESULT: embedded blocks in sync with tools\ sources" -ForegroundColor Green +exit 0 diff --git a/tests/Run-Resolve-Tests.ps1 b/tests/Run-Resolve-Tests.ps1 index 01a6974..aaee014 100644 --- a/tests/Run-Resolve-Tests.ps1 +++ b/tests/Run-Resolve-Tests.ps1 @@ -29,6 +29,18 @@ function Eq([string]$name, $expected, $actual) { Ok $name ("$expected" -eq "$act # Run the engine as a child process (exactly how blueStackRoot.cmd calls it). function Eng([string[]]$a) { & powershell -NoProfile -ExecutionPolicy Bypass -File $Engine @a 2>&1 } +# Expand any 8.3 short path component (e.g. CI's C:\Users\RUNNER~1\... for 'runneradmin') to its long +# form. The engine resolves the on-disk Root.vhd, so it returns the long path; without this the expected +# string (built from $env:TEMP, which the runner reports short) would mismatch purely on 8.3 vs long. +Add-Type -ErrorAction SilentlyContinue -Name Native -Namespace BSR -MemberDefinition ' +[System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode)] +public static extern uint GetLongPathName(string lpszShortPath, System.Text.StringBuilder lpszLongPath, uint cchBuffer);' +function Long([string]$p) { + if (-not $p) { return $p } + try { $sb = New-Object System.Text.StringBuilder 1024; $n = [BSR.Native]::GetLongPathName($p, $sb, 1024); if ($n -gt 0 -and $n -lt 1024) { return $sb.ToString() } } catch { } + return $p +} + # --------------------------------------------------------------------------- # Build a throwaway BlueStacks-shaped DataDir at a NON-default (custom) location. # --------------------------------------------------------------------------- @@ -47,7 +59,7 @@ function New-FakeData([string]$instance, [hashtable]$confKeys, [string]$tag = 'r '' [IO.File]::WriteAllText((Join-Path $eng "$instance.bstk"), $bstk) [IO.File]::WriteAllBytes((Join-Path $eng 'Root.vhd'), (New-Object byte[] 64)) - return $root + return (Long $root) # long-path form so expected paths match the engine's disk-resolved VHD path } function Resolve-Map([string]$dataDir, [string]$base) { $out = Eng @('-Action', 'Resolve', '-DataDir', $dataDir, '-Base', $base) diff --git a/todolist.md b/todolist.md index 7bf51a9..c6655c6 100644 --- a/todolist.md +++ b/todolist.md @@ -38,6 +38,12 @@ column below; coloured via PowerShell `Write-Host` so box-drawing renders regardless of code page. Typos re-prompt instantly (`:prompt`) instead of a full redraw. (Menu lives in the batch portion, so no re-embed is needed for these changes.) +- [x] **CI replaced:** dropped the bogus `Compile and Release` workflow (it `g++`-compiled a since-deleted + `Magisk.cpp` -- always failing -- and its release step would have clobbered hand-cut releases with + nonexistent `magisk.exe`/`NewblueStacksRoot.cmd`). New `.github/workflows/tests.yml` runs on push/PR + to `main`: `tests/Run-Tests.ps1` (28) + `tests/Run-Resolve-Tests.ps1` (22) on windows-latest, plus a + new `tests/Check-Embedded-Sync.ps1` guarding that the embedded engine/orchestrator still match + `tools\bsr_engine.ps1`/`bsr_magisk.ps1`. No auto-compile, no auto-release (releases are cut by hand). ## Open / nice-to-have - [ ] optional: dedicated per-instance Root.vhd (separate VHD + UUID) for a *bit-pristine* `/system` on