Make the standalone exe work with OCR out of the box — no separate
Tesseract install, no tesserocr DLL hell. Verified end-to-end: built the
exe, ran it frozen with the system Tesseract blinded, confirmed it
resolves the bundled binary and reads text ("CHAM RUNE").
- ocr.py: resolve an _APP_BASE (exe dir when frozen, else cwd) and prefer
a bundled <exe_dir>/tesseract/tesseract.exe over PATH / Program Files.
Resolve assets/tessdata to an absolute path so OCR no longer depends on
the current working dir. Applies to both the tesserocr and pytesseract
paths.
- build.py: copy a portable Tesseract (exe + DLLs) from TESSERACT_DIR
(default C:\Program Files\Tesseract-OCR) into <release>/tesseract/. Our
trained models in assets/tessdata are used via --tessdata-dir, so their
tessdata is skipped. Warns (non-fatal) if Tesseract isn't present.
- ci.yml: choco install tesseract before the build so the bundle is
reproducible on the runner; verify it landed in the release dir.
- test/conftest.py: apply the SSL cert-store workaround so pytest can be
collected on Windows boxes with a corrupted cert store (no-op on CI).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
168 lines
5.7 KiB
YAML
168 lines
5.7 KiB
YAML
name: Botty - CI
|
|
on:
|
|
workflow_dispatch:
|
|
pull_request:
|
|
push:
|
|
branches: [main, mine]
|
|
# Pushing a version tag (e.g. `git tag v0.8.5 && git push --tags`) builds,
|
|
# smoke-tests, then creates the GitHub release with the zip attached — all
|
|
# in one run. If the build fails, no release is ever created.
|
|
tags: ['v*']
|
|
|
|
# Default GITHUB_TOKEN is read-only; the build job's release step needs
|
|
# contents:write to create the release and attach the built zip
|
|
# (else HTTP 403 "Resource not accessible by integration").
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Miniconda Python 3.10
|
|
uses: conda-incubator/setup-miniconda@v3
|
|
with:
|
|
python-version: '3.10'
|
|
activate-environment: botty
|
|
channel-priority: strict
|
|
environment-file: environment-win11.yml
|
|
use-only-tar-bz2: false
|
|
|
|
- name: Python version
|
|
shell: powershell
|
|
run: |
|
|
C:\Miniconda\condabin\conda.bat activate botty
|
|
python -c "import sys; print(sys.version)"
|
|
|
|
- name: Syntax check
|
|
shell: powershell
|
|
env:
|
|
PYTHONPATH: ./src
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
C:\Miniconda\condabin\conda.bat activate botty
|
|
python -m compileall -q src tools test scripts
|
|
|
|
- name: Tests
|
|
shell: powershell
|
|
env:
|
|
PYTHONPATH: ./src
|
|
RUN_ENV: test
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
C:\Miniconda\condabin\conda.bat activate botty
|
|
coverage run -m pytest -v
|
|
|
|
- name: Coverage report
|
|
shell: powershell
|
|
env:
|
|
PYTHONPATH: ./src
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
C:\Miniconda\condabin\conda.bat activate botty
|
|
coverage xml --ignore-errors
|
|
|
|
build:
|
|
needs: test
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Miniconda Python 3.10
|
|
uses: conda-incubator/setup-miniconda@v3
|
|
with:
|
|
python-version: '3.10'
|
|
activate-environment: botty
|
|
channel-priority: strict
|
|
environment-file: environment-win11.yml
|
|
use-only-tar-bz2: false
|
|
|
|
- name: Install Tesseract (bundled into the release for click-and-run OCR)
|
|
shell: powershell
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
choco install tesseract --no-progress -y
|
|
if (-not (Test-Path "C:\Program Files\Tesseract-OCR\tesseract.exe")) {
|
|
throw "Tesseract install did not produce tesseract.exe"
|
|
}
|
|
|
|
- name: Build exe
|
|
shell: powershell
|
|
env:
|
|
BOTTY_NO_RENAME: '1'
|
|
PYTHONPATH: ./src
|
|
run: |
|
|
C:\Miniconda\condabin\conda.bat activate botty
|
|
python build.py --conda_path C:\Miniconda
|
|
|
|
- name: Verify Tesseract was bundled
|
|
shell: powershell
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
$BOTTY_DIR = Get-ChildItem -Directory -Name | Where-Object { $_ -match '^botty_v' } | Select-Object -First 1
|
|
$tess = Join-Path $BOTTY_DIR "tesseract\tesseract.exe"
|
|
if (-not (Test-Path $tess)) { throw "Tesseract was not bundled into $BOTTY_DIR" }
|
|
Write-Host "Bundled: $tess"
|
|
|
|
- name: Launch smoke test (built executables)
|
|
shell: powershell
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
$BOTTY_DIR = Get-ChildItem -Directory -Name | Where-Object { $_ -match '^botty_v' } | Select-Object -First 1
|
|
if (-not $BOTTY_DIR) { throw "No botty_v* build directory found." }
|
|
|
|
$mainExe = Join-Path $BOTTY_DIR "main.exe"
|
|
$shopperExe = Join-Path $BOTTY_DIR "shopper.exe"
|
|
if (-not (Test-Path $mainExe)) { throw "Missing $mainExe" }
|
|
if (-not (Test-Path $shopperExe)) { throw "Missing $shopperExe" }
|
|
|
|
$procs = @()
|
|
try {
|
|
$mainProc = Start-Process -FilePath $mainExe -PassThru -WindowStyle Hidden
|
|
Start-Sleep -Seconds 6
|
|
if ($mainProc.HasExited) { throw "main.exe exited early with code $($mainProc.ExitCode)" }
|
|
$procs += $mainProc
|
|
|
|
$shopperProc = Start-Process -FilePath $shopperExe -PassThru -WindowStyle Hidden
|
|
Start-Sleep -Seconds 6
|
|
if ($shopperProc.HasExited) { throw "shopper.exe exited early with code $($shopperProc.ExitCode)" }
|
|
$procs += $shopperProc
|
|
}
|
|
finally {
|
|
foreach ($p in $procs) {
|
|
if ($p -and -not $p.HasExited) {
|
|
Stop-Process -Id $p.Id -Force
|
|
}
|
|
}
|
|
}
|
|
|
|
- name: Prepare release zip
|
|
shell: powershell
|
|
run: |
|
|
$BOTTY_DIR = Get-ChildItem -Directory -Name | Where-Object { $_ -match '^botty_v' } | Select-Object -First 1
|
|
Write-Host "Botty dir: $BOTTY_DIR"
|
|
Get-ChildItem -Path $BOTTY_DIR -Recurse | Select-Object -Property FullName, Length
|
|
$ZIP = "${BOTTY_DIR}.zip"
|
|
Compress-Archive -Path "${BOTTY_DIR}\*" -DestinationPath $ZIP -Force
|
|
Write-Host "Release zip: $ZIP"
|
|
Get-Item $ZIP | Select-Object -Property FullName, Length
|
|
|
|
- name: Upload build artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: botty-build
|
|
path: botty_v*/
|
|
retention-days: 7
|
|
|
|
# On a version-tag push, create the release (if absent) and attach the
|
|
# zip atomically. Runs only after the build + smoke test above succeed.
|
|
- name: Create release and upload zip
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
files: botty_v*.zip
|
|
fail_on_unmatched_files: true
|
|
generate_release_notes: true
|