Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 100 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
test "${{ inputs.release_tag }}" = "v${version}"
fi
- run: cargo fmt --all -- --check
- run: cargo test --workspace --all-features --locked
- run: cargo test --workspace --all-features --locked -- --test-threads=1
- run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings

binaries:
Expand Down Expand Up @@ -84,12 +84,16 @@ jobs:
version="${{ needs.validate.outputs.version }}"
archive="a3s-use-${version}-${{ matrix.name }}.tar.gz"
stage="${RUNNER_TEMP}/a3s-use-${version}-${{ matrix.name }}"
install -d "${stage}/skills" "${stage}/skill-data" "${stage}/office-skills" "${stage}/dashboard"
install -d "${stage}/skills" "${stage}/skill-data" "${stage}/office-skills" "${stage}/ocr-skills" "${stage}/dashboard"
install -m 0755 "target/${{ matrix.target }}/release/a3s-use" "${stage}/a3s-use"
install -m 0755 "target/${{ matrix.target }}/release/a3s-use-browser-driver" "${stage}/a3s-use-browser-driver"
A3S_USE_OCR_HOME="${stage}/ocr-models" \
"${stage}/a3s-use" component install ocr --json > "${RUNNER_TEMP}/ocr-model-install.json"
rm -f "${stage}/ocr-models/.install.lock"
cp -R crates/browser-driver/skills/. "${stage}/skills/"
cp -R crates/browser-driver/skill-data/. "${stage}/skill-data/"
cp -R crates/office/skills/. "${stage}/office-skills/"
cp -R crates/ocr/skills/. "${stage}/ocr-skills/"
cp -R crates/browser-driver/dashboard/out/. "${stage}/dashboard/"
install -m 0644 LICENSE README.md THIRD_PARTY_NOTICES.md "${stage}/"
install -m 0644 crates/browser-driver/LICENSE-APACHE-2.0 "${stage}/LICENSE-APACHE-2.0"
Expand All @@ -107,9 +111,15 @@ jobs:
New-Item -ItemType Directory -Force -Path $stage | Out-Null
Copy-Item "target/${{ matrix.target }}/release/a3s-use.exe" "$stage/a3s-use.exe"
Copy-Item "target/${{ matrix.target }}/release/a3s-use-browser-driver.exe" "$stage/a3s-use-browser-driver.exe"
$env:A3S_USE_OCR_HOME = "$stage/ocr-models"
& "$stage/a3s-use.exe" component install ocr --json | Out-File "$env:RUNNER_TEMP/ocr-model-install.json"
if ($LASTEXITCODE -ne 0) { throw "Failed to install the pinned PP-OCRv6 release assets" }
Remove-Item Env:A3S_USE_OCR_HOME
Remove-Item "$stage/ocr-models/.install.lock" -ErrorAction SilentlyContinue
Copy-Item -Recurse "crates/browser-driver/skills" "$stage/skills"
Copy-Item -Recurse "crates/browser-driver/skill-data" "$stage/skill-data"
Copy-Item -Recurse "crates/office/skills" "$stage/office-skills"
Copy-Item -Recurse "crates/ocr/skills" "$stage/ocr-skills"
Copy-Item -Recurse "crates/browser-driver/dashboard/out" "$stage/dashboard"
Copy-Item LICENSE,README.md,THIRD_PARTY_NOTICES.md $stage
Copy-Item crates/browser-driver/LICENSE-APACHE-2.0 "$stage/LICENSE-APACHE-2.0"
Expand All @@ -128,6 +138,11 @@ jobs:
test -x "${install_root}/a3s-use-browser-driver"
test -f "${install_root}/skill-data/core/SKILL.md"
test -f "${install_root}/office-skills/a3s-use-office/SKILL.md"
test -f "${install_root}/ocr-skills/a3s-use-ocr/SKILL.md"
test -f "${install_root}/ocr-models/PP-OCRv6_small/det/inference.onnx"
test -f "${install_root}/ocr-models/PP-OCRv6_small/det/inference.yml"
test -f "${install_root}/ocr-models/PP-OCRv6_small/rec/inference.onnx"
test -f "${install_root}/ocr-models/PP-OCRv6_small/rec/inference.yml"
test -f "${install_root}/dashboard/index.html"
test -f "${install_root}/LICENSE-APACHE-2.0"
test -f "${install_root}/UPSTREAM.md"
Expand All @@ -143,6 +158,49 @@ jobs:
"agentcore", "core", "dogfood", "electron", "slack", "vercel-sandbox"
}
PY
"${install_root}/a3s-use" ocr doctor --json > "${RUNNER_TEMP}/ocr-doctor.json"
python3 - "${RUNNER_TEMP}/ocr-doctor.json" <<'PY'
import json, pathlib, sys
value = json.loads(pathlib.Path(sys.argv[1]).read_text())
assert value["ok"] is True
assert value["data"]["readiness"] == "ready"
assert value["data"]["provider"] == "pp-ocr-v6"
assert value["data"]["engine"] == "onnx-runtime"
assert value["data"]["model"] == "PP-OCRv6_small"
assert value["data"]["sendsSourceOffDevice"] is False
PY
python3 - "${RUNNER_TEMP}/ocr-white.bmp" <<'PY'
import base64, pathlib, sys
pathlib.Path(sys.argv[1]).write_bytes(base64.b64decode(
"Qk06AAAAAAAAADYAAAAoAAAAAQAAAAEAAAABABgAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA////AA=="
))
PY
"${install_root}/a3s-use" ocr extract "${RUNNER_TEMP}/ocr-white.bmp" --json > "${RUNNER_TEMP}/ocr-extract.json"
python3 - "${RUNNER_TEMP}/ocr-extract.json" <<'PY'
import json, pathlib, sys
value = json.loads(pathlib.Path(sys.argv[1]).read_text())
assert value["ok"] is True
assert value["data"]["provider"] == "pp-ocr-v6"
assert value["data"]["engine"] == "onnx-runtime"
assert value["data"]["model"] == "PP-OCRv6_small"
assert value["data"]["source"]["mediaType"] == "image/bmp"
PY
"${install_root}/a3s-use" capability snapshot --json > "${RUNNER_TEMP}/capabilities.json"
python3 - "${RUNNER_TEMP}/capabilities.json" "${install_root}" <<'PY'
import json, pathlib, sys
value = json.loads(pathlib.Path(sys.argv[1]).read_text())
root = pathlib.Path(sys.argv[2]).resolve()
ocr = next(
capability
for capability in value["data"]["registry"]["capabilities"]
if capability["id"] == "use/ocr"
)
assert ocr["mcp"]["target"] == "ocr-native"
assert len(ocr["skills"]) == 1
assert pathlib.Path(ocr["skills"][0]["path"]).resolve() == (
root / "ocr-skills" / "a3s-use-ocr" / "SKILL.md"
)
PY
A3S_OFFICECLI_EXECUTABLE="${install_root}/must-not-be-invoked" \
"${install_root}/a3s-use" office skills list --json > "${RUNNER_TEMP}/office-skills.json"
python3 - "${RUNNER_TEMP}/office-skills.json" <<'PY'
Expand Down Expand Up @@ -179,6 +237,11 @@ jobs:
"$root/a3s-use-browser-driver.exe",
"$root/skill-data/core/SKILL.md",
"$root/office-skills/a3s-use-office/SKILL.md",
"$root/ocr-skills/a3s-use-ocr/SKILL.md",
"$root/ocr-models/PP-OCRv6_small/det/inference.onnx",
"$root/ocr-models/PP-OCRv6_small/det/inference.yml",
"$root/ocr-models/PP-OCRv6_small/rec/inference.onnx",
"$root/ocr-models/PP-OCRv6_small/rec/inference.yml",
"$root/dashboard/index.html",
"$root/LICENSE-APACHE-2.0",
"$root/UPSTREAM.md",
Expand All @@ -194,6 +257,36 @@ jobs:
if (-not $officeSkills.ok -or $officeSkills.data.Count -ne 1 -or $officeSkills.data[0].name -ne "a3s-use-office") {
throw "Packaged Office Skill smoke failed"
}
$ocr = (& "$root/a3s-use.exe" ocr doctor --json | ConvertFrom-Json)
if (
-not $ocr.ok -or
$ocr.data.readiness -ne "ready" -or
$ocr.data.provider -ne "pp-ocr-v6" -or
$ocr.data.engine -ne "onnx-runtime" -or
$ocr.data.model -ne "PP-OCRv6_small" -or
$ocr.data.sendsSourceOffDevice
) { throw "Packaged PP-OCRv6 doctor smoke failed" }
$whiteBmp = [Convert]::FromBase64String("Qk06AAAAAAAAADYAAAAoAAAAAQAAAAEAAAABABgAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA////AA==")
[IO.File]::WriteAllBytes("$env:RUNNER_TEMP/ocr-white.bmp", $whiteBmp)
$ocrExtract = (& "$root/a3s-use.exe" ocr extract "$env:RUNNER_TEMP/ocr-white.bmp" --json | ConvertFrom-Json)
if (
-not $ocrExtract.ok -or
$ocrExtract.data.provider -ne "pp-ocr-v6" -or
$ocrExtract.data.engine -ne "onnx-runtime" -or
$ocrExtract.data.model -ne "PP-OCRv6_small" -or
$ocrExtract.data.source.mediaType -ne "image/bmp"
) { throw "Packaged PP-OCRv6 extraction smoke failed" }
$capabilities = (& "$root/a3s-use.exe" capability snapshot --json | ConvertFrom-Json)
$ocrCapability = $capabilities.data.registry.capabilities |
Where-Object id -eq "use/ocr"
if ($ocrCapability.mcp.target -ne "ocr-native" -or $ocrCapability.skills.Count -ne 1) {
throw "Built-in OCR capability projection smoke failed"
}
$expectedOcrSkill = (Resolve-Path "$root/ocr-skills/a3s-use-ocr/SKILL.md").Path
$actualOcrSkill = (Resolve-Path $ocrCapability.skills[0].path).Path
if (-not [StringComparer]::OrdinalIgnoreCase.Equals($actualOcrSkill, $expectedOcrSkill)) {
throw "Built-in OCR Skill was not projected from the installed release"
}
$requests = @(
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"release-smoke","version":"1"}}}',
'{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}',
Expand Down Expand Up @@ -223,7 +316,7 @@ jobs:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref }}
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Publish Core then Browser
- name: Publish Core, Extension, OCR, then Browser
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_TOKEN }}
VERSION: ${{ needs.validate.outputs.version }}
Expand Down Expand Up @@ -262,6 +355,10 @@ jobs:

publish_once a3s-use-core
wait_until_visible a3s-use-core
publish_once a3s-use-extension
wait_until_visible a3s-use-extension
publish_once a3s-use-ocr
wait_until_visible a3s-use-ocr
publish_once a3s-use-browser

release:
Expand Down
Loading
Loading