yazses 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- yazses-0.4.1/.github/workflows/apt-repo.yml +91 -0
- yazses-0.4.1/.github/workflows/build-macos.yml +160 -0
- yazses-0.4.1/.github/workflows/build-windows.yml +141 -0
- yazses-0.4.1/.github/workflows/ppa.yml +51 -0
- yazses-0.4.1/.github/workflows/release.yml +148 -0
- yazses-0.4.1/.github/workflows/snap.yml +74 -0
- yazses-0.4.1/.github/workflows/test.yml +38 -0
- yazses-0.4.1/.gitignore +254 -0
- yazses-0.4.1/CHANGELOG.md +241 -0
- yazses-0.4.1/LICENSE +201 -0
- yazses-0.4.1/PKG-INFO +428 -0
- yazses-0.4.1/README.md +374 -0
- yazses-0.4.1/ROADMAP.md +89 -0
- yazses-0.4.1/contrib/yazses.service +16 -0
- yazses-0.4.1/debian/changelog +5 -0
- yazses-0.4.1/debian/control +21 -0
- yazses-0.4.1/debian/copyright +19 -0
- yazses-0.4.1/debian/postinst +17 -0
- yazses-0.4.1/debian/prerm +12 -0
- yazses-0.4.1/debian/rules +13 -0
- yazses-0.4.1/debian/source/format +1 -0
- yazses-0.4.1/docs/adr/adr-v04-001-slm-inference.md +89 -0
- yazses-0.4.1/docs/adr/adr-v04-002-lsp-context.md +102 -0
- yazses-0.4.1/docs/adr/adr-v04-003-emg-serial.md +106 -0
- yazses-0.4.1/docs/apt-repo-setup.md +52 -0
- yazses-0.4.1/docs/architecture.md +270 -0
- yazses-0.4.1/docs/distribution-status.md +127 -0
- yazses-0.4.1/docs/emg-protocol.md +174 -0
- yazses-0.4.1/docs/macos-install.md +128 -0
- yazses-0.4.1/docs/macos-signing.md +104 -0
- yazses-0.4.1/docs/ppa-setup.md +41 -0
- yazses-0.4.1/docs/snap-setup.md +49 -0
- yazses-0.4.1/docs/superpowers/plans/2026-05-08-distribution-channels.md +869 -0
- yazses-0.4.1/docs/windows-install.md +115 -0
- yazses-0.4.1/docs/windows-signing.md +80 -0
- yazses-0.4.1/examples/config.example.toml +23 -0
- yazses-0.4.1/install-apt.sh +85 -0
- yazses-0.4.1/install.sh +94 -0
- yazses-0.4.1/packaging/README.md +76 -0
- yazses-0.4.1/packaging/arch/PKGBUILD +114 -0
- yazses-0.4.1/packaging/arch/README.md +75 -0
- yazses-0.4.1/packaging/homebrew/yazses.rb +44 -0
- yazses-0.4.1/packaging/macos/entitlements.plist +21 -0
- yazses-0.4.1/packaging/macos/yazses.spec +123 -0
- yazses-0.4.1/packaging/windows/installer.iss +79 -0
- yazses-0.4.1/packaging/windows/yazses.spec +88 -0
- yazses-0.4.1/packaging/winget/manifests/n/NovaFabric/YazSes/0.2.0/NovaFabric.YazSes.installer.yaml +31 -0
- yazses-0.4.1/packaging/winget/manifests/n/NovaFabric/YazSes/0.2.0/NovaFabric.YazSes.locale.en-US.yaml +46 -0
- yazses-0.4.1/packaging/winget/manifests/n/NovaFabric/YazSes/0.2.0/NovaFabric.YazSes.yaml +16 -0
- yazses-0.4.1/pyproject.toml +93 -0
- yazses-0.4.1/scripts/build-deb.sh +95 -0
- yazses-0.4.1/scripts/build-macos.sh +67 -0
- yazses-0.4.1/scripts/build-windows.ps1 +84 -0
- yazses-0.4.1/scripts/update-apt-repo.sh +94 -0
- yazses-0.4.1/scripts/upload-ppa.sh +38 -0
- yazses-0.4.1/snap/local/yazses-daemon-wrapper +5 -0
- yazses-0.4.1/snap/local/yazses-tray-wrapper +5 -0
- yazses-0.4.1/snap/local/yazses-wrapper +5 -0
- yazses-0.4.1/snap/snapcraft.yaml +59 -0
- yazses-0.4.1/src/yazses/__init__.py +1 -0
- yazses-0.4.1/src/yazses/__main__.py +46 -0
- yazses-0.4.1/src/yazses/accessibility/__init__.py +0 -0
- yazses-0.4.1/src/yazses/accessibility/enroll.py +181 -0
- yazses-0.4.1/src/yazses/audio/__init__.py +0 -0
- yazses-0.4.1/src/yazses/audio/padding.py +75 -0
- yazses-0.4.1/src/yazses/audio/recorder.py +60 -0
- yazses-0.4.1/src/yazses/audio/vad.py +9 -0
- yazses-0.4.1/src/yazses/audio/vad_calibrated.py +16 -0
- yazses-0.4.1/src/yazses/cli.py +225 -0
- yazses-0.4.1/src/yazses/commands/__init__.py +0 -0
- yazses-0.4.1/src/yazses/commands/dispatch.py +146 -0
- yazses-0.4.1/src/yazses/commands/grammar.py +115 -0
- yazses-0.4.1/src/yazses/commands/lsp_context.py +370 -0
- yazses-0.4.1/src/yazses/commands/model_manager.py +118 -0
- yazses-0.4.1/src/yazses/commands/profiles.py +21 -0
- yazses-0.4.1/src/yazses/commands/slm_router.py +231 -0
- yazses-0.4.1/src/yazses/config.py +162 -0
- yazses-0.4.1/src/yazses/core/__init__.py +0 -0
- yazses-0.4.1/src/yazses/core/daemon.py +508 -0
- yazses-0.4.1/src/yazses/hotkeys/__init__.py +0 -0
- yazses-0.4.1/src/yazses/hotkeys/evdev_hold.py +79 -0
- yazses-0.4.1/src/yazses/hotkeys/hold_detector.py +32 -0
- yazses-0.4.1/src/yazses/inject/__init__.py +0 -0
- yazses-0.4.1/src/yazses/inject/auto.py +21 -0
- yazses-0.4.1/src/yazses/inject/base.py +8 -0
- yazses-0.4.1/src/yazses/inject/clipboard.py +80 -0
- yazses-0.4.1/src/yazses/inject/streaming.py +59 -0
- yazses-0.4.1/src/yazses/inject/wtype.py +31 -0
- yazses-0.4.1/src/yazses/inject/xdotool.py +28 -0
- yazses-0.4.1/src/yazses/inject/ydotool.py +20 -0
- yazses-0.4.1/src/yazses/ipc/__init__.py +0 -0
- yazses-0.4.1/src/yazses/ipc/client.py +85 -0
- yazses-0.4.1/src/yazses/ipc/protocol.py +100 -0
- yazses-0.4.1/src/yazses/ipc/server.py +169 -0
- yazses-0.4.1/src/yazses/main.py +7 -0
- yazses-0.4.1/src/yazses/platform/__init__.py +33 -0
- yazses-0.4.1/src/yazses/platform/base.py +205 -0
- yazses-0.4.1/src/yazses/platform/emg/__init__.py +0 -0
- yazses-0.4.1/src/yazses/platform/emg/backend.py +150 -0
- yazses-0.4.1/src/yazses/platform/emg/ble_backend.py +144 -0
- yazses-0.4.1/src/yazses/platform/factory.py +30 -0
- yazses-0.4.1/src/yazses/platform/linux/__init__.py +39 -0
- yazses-0.4.1/src/yazses/platform/linux/hotkey.py +79 -0
- yazses-0.4.1/src/yazses/platform/linux/injector.py +119 -0
- yazses-0.4.1/src/yazses/platform/linux/ipc.py +20 -0
- yazses-0.4.1/src/yazses/platform/linux/lifecycle.py +85 -0
- yazses-0.4.1/src/yazses/platform/linux/paths.py +22 -0
- yazses-0.4.1/src/yazses/platform/linux/permissions.py +43 -0
- yazses-0.4.1/src/yazses/platform/macos/__init__.py +44 -0
- yazses-0.4.1/src/yazses/platform/macos/hotkey.py +259 -0
- yazses-0.4.1/src/yazses/platform/macos/injector.py +137 -0
- yazses-0.4.1/src/yazses/platform/macos/ipc.py +18 -0
- yazses-0.4.1/src/yazses/platform/macos/lifecycle.py +140 -0
- yazses-0.4.1/src/yazses/platform/macos/paths.py +24 -0
- yazses-0.4.1/src/yazses/platform/macos/permissions.py +80 -0
- yazses-0.4.1/src/yazses/platform/macos/tray.py +92 -0
- yazses-0.4.1/src/yazses/platform/windows/__init__.py +46 -0
- yazses-0.4.1/src/yazses/platform/windows/hotkey.py +211 -0
- yazses-0.4.1/src/yazses/platform/windows/injector.py +168 -0
- yazses-0.4.1/src/yazses/platform/windows/ipc.py +238 -0
- yazses-0.4.1/src/yazses/platform/windows/lifecycle.py +152 -0
- yazses-0.4.1/src/yazses/platform/windows/paths.py +24 -0
- yazses-0.4.1/src/yazses/platform/windows/permissions.py +47 -0
- yazses-0.4.1/src/yazses/platform/windows/tray.py +100 -0
- yazses-0.4.1/src/yazses/postprocess/__init__.py +0 -0
- yazses-0.4.1/src/yazses/postprocess/cleaner.py +11 -0
- yazses-0.4.1/src/yazses/remote/__init__.py +0 -0
- yazses-0.4.1/src/yazses/remote/agent.py +95 -0
- yazses-0.4.1/src/yazses/remote/forwarder.py +100 -0
- yazses-0.4.1/src/yazses/remote/inject.py +65 -0
- yazses-0.4.1/src/yazses/remote/local_proxy.py +72 -0
- yazses-0.4.1/src/yazses/stt/__init__.py +0 -0
- yazses-0.4.1/src/yazses/stt/faster_whisper.py +32 -0
- yazses-0.4.1/src/yazses/stt/filters/__init__.py +0 -0
- yazses-0.4.1/src/yazses/stt/filters/disfluency.py +132 -0
- yazses-0.4.1/src/yazses/stt/streaming.py +150 -0
- yazses-0.4.1/src/yazses/system/__init__.py +0 -0
- yazses-0.4.1/src/yazses/system/doctor.py +102 -0
- yazses-0.4.1/src/yazses/system/pid.py +41 -0
- yazses-0.4.1/src/yazses/tray/__init__.py +0 -0
- yazses-0.4.1/src/yazses/tray/app.py +105 -0
- yazses-0.4.1/tests/__init__.py +0 -0
- yazses-0.4.1/tests/conftest.py +15 -0
- yazses-0.4.1/tests/fixtures/accessibility/rms_stats.json +5 -0
- yazses-0.4.1/tests/fixtures/commands/command_phrases.json +70 -0
- yazses-0.4.1/tests/fixtures/commands/dictation_corpus.txt +87 -0
- yazses-0.4.1/tests/fixtures/disfluency/corpus.json +162 -0
- yazses-0.4.1/tests/test_accessibility_enroll.py +81 -0
- yazses-0.4.1/tests/test_audio_padding.py +82 -0
- yazses-0.4.1/tests/test_auto_inject.py +44 -0
- yazses-0.4.1/tests/test_cleaner.py +51 -0
- yazses-0.4.1/tests/test_config.py +43 -0
- yazses-0.4.1/tests/test_disfluency_filter.py +81 -0
- yazses-0.4.1/tests/test_emg_backend.py +309 -0
- yazses-0.4.1/tests/test_grammar_classifier.py +103 -0
- yazses-0.4.1/tests/test_hold_detector.py +62 -0
- yazses-0.4.1/tests/test_ipc_protocol.py +141 -0
- yazses-0.4.1/tests/test_lsp_context.py +225 -0
- yazses-0.4.1/tests/test_platform_factory.py +69 -0
- yazses-0.4.1/tests/test_platform_macos.py +96 -0
- yazses-0.4.1/tests/test_platform_windows.py +106 -0
- yazses-0.4.1/tests/test_remote_agent.py +158 -0
- yazses-0.4.1/tests/test_slm_router.py +177 -0
- yazses-0.4.1/tests/test_streaming_engine.py +91 -0
- yazses-0.4.1/tests/test_streaming_injector.py +90 -0
- yazses-0.4.1/tests/test_vad_calibrated.py +43 -0
- yazses-0.4.1/uv.lock +1813 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
name: APT Repository
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows: ["Release"]
|
|
6
|
+
types: [completed]
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
run_id:
|
|
10
|
+
description: "Release workflow run ID (optional, uses latest if empty)"
|
|
11
|
+
required: false
|
|
12
|
+
default: ""
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
16
|
+
|
|
17
|
+
concurrency:
|
|
18
|
+
group: apt-repo-${{ github.repository }}
|
|
19
|
+
cancel-in-progress: false
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
update-apt-repo:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
timeout-minutes: 15
|
|
25
|
+
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
|
|
26
|
+
permissions:
|
|
27
|
+
contents: write
|
|
28
|
+
actions: read
|
|
29
|
+
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
with:
|
|
33
|
+
fetch-depth: 0
|
|
34
|
+
|
|
35
|
+
- name: Determine release run ID
|
|
36
|
+
id: run_id
|
|
37
|
+
env:
|
|
38
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
39
|
+
run: |
|
|
40
|
+
MANUAL_ID="${{ github.event.inputs.run_id }}"
|
|
41
|
+
EVENT_ID="${{ github.event.workflow_run.id }}"
|
|
42
|
+
if [ -n "$MANUAL_ID" ]; then
|
|
43
|
+
echo "id=$MANUAL_ID" >> $GITHUB_OUTPUT
|
|
44
|
+
elif [ -n "$EVENT_ID" ]; then
|
|
45
|
+
echo "id=$EVENT_ID" >> $GITHUB_OUTPUT
|
|
46
|
+
else
|
|
47
|
+
# Auto-detect: find latest successful Release run that has a deb-package artifact
|
|
48
|
+
RUN_ID=$(gh api "repos/$GITHUB_REPOSITORY/actions/workflows/release.yml/runs?status=completed&per_page=10" \
|
|
49
|
+
--jq '.workflow_runs[] | select(.conclusion=="success" or .conclusion=="failure") | .id' \
|
|
50
|
+
| head -1)
|
|
51
|
+
echo "id=$RUN_ID" >> $GITHUB_OUTPUT
|
|
52
|
+
echo "Auto-detected release run ID: $RUN_ID"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
- name: Download .deb artifact from release workflow
|
|
56
|
+
uses: actions/download-artifact@v4
|
|
57
|
+
with:
|
|
58
|
+
name: deb-package
|
|
59
|
+
path: /tmp/debs
|
|
60
|
+
run-id: ${{ steps.run_id.outputs.id }}
|
|
61
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
62
|
+
|
|
63
|
+
- name: Import GPG signing key
|
|
64
|
+
env:
|
|
65
|
+
GPG_PRIVATE_KEY: ${{ secrets.APT_REPO_GPG_PRIVATE_KEY }}
|
|
66
|
+
GPG_KEY_ID: ${{ secrets.APT_REPO_GPG_KEY_ID }}
|
|
67
|
+
run: |
|
|
68
|
+
set -euo pipefail
|
|
69
|
+
|
|
70
|
+
test -n "$GPG_PRIVATE_KEY" || { echo "::error::APT_REPO_GPG_PRIVATE_KEY secret is empty or missing"; exit 1; }
|
|
71
|
+
test -n "$GPG_KEY_ID" || { echo "::error::APT_REPO_GPG_KEY_ID secret is empty or missing"; exit 1; }
|
|
72
|
+
|
|
73
|
+
mkdir -p ~/.gnupg
|
|
74
|
+
chmod 700 ~/.gnupg
|
|
75
|
+
printf 'allow-loopback-pinentry\n' > ~/.gnupg/gpg-agent.conf
|
|
76
|
+
gpgconf --kill gpg-agent || true
|
|
77
|
+
|
|
78
|
+
printf '%s\n' "$GPG_PRIVATE_KEY" | gpg --batch --yes --import
|
|
79
|
+
echo "$GPG_KEY_ID:6:" | gpg --import-ownertrust
|
|
80
|
+
gpg --list-secret-keys "$GPG_KEY_ID"
|
|
81
|
+
|
|
82
|
+
echo "" > /tmp/gpg-passphrase
|
|
83
|
+
|
|
84
|
+
- name: Update apt repository
|
|
85
|
+
env:
|
|
86
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
87
|
+
GPG_KEY_ID: ${{ secrets.APT_REPO_GPG_KEY_ID }}
|
|
88
|
+
run: |
|
|
89
|
+
debs=(/tmp/debs/*.deb)
|
|
90
|
+
[[ ${#debs[@]} -eq 1 ]] || { echo "Expected 1 .deb, got ${#debs[@]}"; exit 1; }
|
|
91
|
+
bash scripts/update-apt-repo.sh "${debs[0]}" "$GPG_KEY_ID"
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
name: build-macos
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ['v*']
|
|
6
|
+
pull_request:
|
|
7
|
+
paths:
|
|
8
|
+
- 'src/yazses/platform/macos/**'
|
|
9
|
+
- 'src/yazses/__main__.py'
|
|
10
|
+
- 'src/yazses/tray/**'
|
|
11
|
+
- 'packaging/macos/**'
|
|
12
|
+
- 'scripts/build-macos.sh'
|
|
13
|
+
- '.github/workflows/build-macos.yml'
|
|
14
|
+
- 'pyproject.toml'
|
|
15
|
+
workflow_dispatch:
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: write # needed by softprops/action-gh-release to attach .dmg to the Release
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
build:
|
|
22
|
+
runs-on: macos-latest
|
|
23
|
+
timeout-minutes: 30
|
|
24
|
+
|
|
25
|
+
env:
|
|
26
|
+
# Apple Developer Program signing + notarisation. All four secrets must
|
|
27
|
+
# be set for the signing path to fire. Otherwise the workflow ships an
|
|
28
|
+
# unsigned dev preview (the v0 default).
|
|
29
|
+
# MACOS_CERTIFICATE — base64 of the Developer ID .p12 keystore
|
|
30
|
+
# MACOS_CERTIFICATE_PWD — password for the .p12
|
|
31
|
+
# MACOS_NOTARY_APPLE_ID — Apple ID email used for notarytool
|
|
32
|
+
# MACOS_NOTARY_PASSWORD — app-specific password from appleid.apple.com
|
|
33
|
+
# MACOS_NOTARY_TEAM_ID — 10-char team ID (Apple Developer Membership)
|
|
34
|
+
# MACOS_SIGNING_IDENTITY — exact "Developer ID Application: <Name> (<Team>)" string
|
|
35
|
+
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
|
36
|
+
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
|
37
|
+
MACOS_NOTARY_APPLE_ID: ${{ secrets.MACOS_NOTARY_APPLE_ID }}
|
|
38
|
+
MACOS_NOTARY_PASSWORD: ${{ secrets.MACOS_NOTARY_PASSWORD }}
|
|
39
|
+
MACOS_NOTARY_TEAM_ID: ${{ secrets.MACOS_NOTARY_TEAM_ID }}
|
|
40
|
+
MACOS_SIGNING_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY }}
|
|
41
|
+
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
|
|
45
|
+
- name: Set up uv
|
|
46
|
+
uses: astral-sh/setup-uv@v5
|
|
47
|
+
with:
|
|
48
|
+
version: '0.5.x'
|
|
49
|
+
|
|
50
|
+
- name: Set up Python
|
|
51
|
+
run: uv python install 3.12
|
|
52
|
+
|
|
53
|
+
- name: Install create-dmg
|
|
54
|
+
run: brew install create-dmg
|
|
55
|
+
|
|
56
|
+
- name: Detect signing presence
|
|
57
|
+
id: sign
|
|
58
|
+
shell: bash
|
|
59
|
+
run: |
|
|
60
|
+
if [[ -n "${MACOS_CERTIFICATE}" \
|
|
61
|
+
&& -n "${MACOS_CERTIFICATE_PWD}" \
|
|
62
|
+
&& -n "${MACOS_NOTARY_APPLE_ID}" \
|
|
63
|
+
&& -n "${MACOS_NOTARY_PASSWORD}" \
|
|
64
|
+
&& -n "${MACOS_NOTARY_TEAM_ID}" \
|
|
65
|
+
&& -n "${MACOS_SIGNING_IDENTITY}" ]]; then
|
|
66
|
+
echo "sign=true" >> "${GITHUB_OUTPUT}"
|
|
67
|
+
echo "Signing + notarisation will run."
|
|
68
|
+
else
|
|
69
|
+
echo "sign=false" >> "${GITHUB_OUTPUT}"
|
|
70
|
+
echo "Signing secrets not all present; producing unsigned dev preview."
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
- name: Import signing certificate into keychain
|
|
74
|
+
if: steps.sign.outputs.sign == 'true'
|
|
75
|
+
shell: bash
|
|
76
|
+
run: |
|
|
77
|
+
KEYCHAIN=yazses-build.keychain-db
|
|
78
|
+
KEYCHAIN_PWD=$(uuidgen)
|
|
79
|
+
security create-keychain -p "${KEYCHAIN_PWD}" "${KEYCHAIN}"
|
|
80
|
+
security set-keychain-settings -lut 21600 "${KEYCHAIN}"
|
|
81
|
+
security unlock-keychain -p "${KEYCHAIN_PWD}" "${KEYCHAIN}"
|
|
82
|
+
|
|
83
|
+
# Decode the base64-encoded .p12 and import it.
|
|
84
|
+
echo -n "${MACOS_CERTIFICATE}" | base64 --decode > /tmp/cert.p12
|
|
85
|
+
security import /tmp/cert.p12 \
|
|
86
|
+
-k "${KEYCHAIN}" \
|
|
87
|
+
-P "${MACOS_CERTIFICATE_PWD}" \
|
|
88
|
+
-T /usr/bin/codesign \
|
|
89
|
+
-T /usr/bin/security
|
|
90
|
+
rm -f /tmp/cert.p12
|
|
91
|
+
|
|
92
|
+
# Allow codesign to use the imported key without a UI prompt.
|
|
93
|
+
security set-key-partition-list \
|
|
94
|
+
-S apple-tool:,apple:,codesign: \
|
|
95
|
+
-s -k "${KEYCHAIN_PWD}" "${KEYCHAIN}" >/dev/null
|
|
96
|
+
security list-keychains -d user -s "${KEYCHAIN}" $(security list-keychains -d user | tr -d '"' | xargs)
|
|
97
|
+
echo "KEYCHAIN_PWD=${KEYCHAIN_PWD}" >> "${GITHUB_ENV}"
|
|
98
|
+
echo "Keychain ready."
|
|
99
|
+
|
|
100
|
+
- name: Build .dmg
|
|
101
|
+
run: ./scripts/build-macos.sh
|
|
102
|
+
|
|
103
|
+
- name: Codesign .app and .dmg (Developer ID)
|
|
104
|
+
if: steps.sign.outputs.sign == 'true'
|
|
105
|
+
shell: bash
|
|
106
|
+
run: |
|
|
107
|
+
set -euo pipefail
|
|
108
|
+
APP="dist/YazSes.app"
|
|
109
|
+
DMG=$(ls dist/YazSes-*.dmg | head -1)
|
|
110
|
+
ENTITLEMENTS=packaging/macos/entitlements.plist
|
|
111
|
+
|
|
112
|
+
echo "==> codesign --deep on the app bundle"
|
|
113
|
+
/usr/bin/codesign \
|
|
114
|
+
--force --deep --options runtime \
|
|
115
|
+
--timestamp \
|
|
116
|
+
--entitlements "${ENTITLEMENTS}" \
|
|
117
|
+
--sign "${MACOS_SIGNING_IDENTITY}" \
|
|
118
|
+
"${APP}"
|
|
119
|
+
|
|
120
|
+
echo "==> codesign on the .dmg itself"
|
|
121
|
+
/usr/bin/codesign \
|
|
122
|
+
--force --timestamp \
|
|
123
|
+
--sign "${MACOS_SIGNING_IDENTITY}" \
|
|
124
|
+
"${DMG}"
|
|
125
|
+
|
|
126
|
+
echo "==> verify"
|
|
127
|
+
/usr/bin/codesign --verify --deep --strict --verbose=2 "${APP}"
|
|
128
|
+
/usr/bin/codesign --verify --verbose=2 "${DMG}"
|
|
129
|
+
|
|
130
|
+
- name: Notarise .dmg with Apple
|
|
131
|
+
if: steps.sign.outputs.sign == 'true'
|
|
132
|
+
shell: bash
|
|
133
|
+
run: |
|
|
134
|
+
set -euo pipefail
|
|
135
|
+
DMG=$(ls dist/YazSes-*.dmg | head -1)
|
|
136
|
+
xcrun notarytool submit "${DMG}" \
|
|
137
|
+
--apple-id "${MACOS_NOTARY_APPLE_ID}" \
|
|
138
|
+
--password "${MACOS_NOTARY_PASSWORD}" \
|
|
139
|
+
--team-id "${MACOS_NOTARY_TEAM_ID}" \
|
|
140
|
+
--wait
|
|
141
|
+
xcrun stapler staple "${DMG}"
|
|
142
|
+
xcrun stapler validate "${DMG}"
|
|
143
|
+
|
|
144
|
+
- name: Show build artefacts
|
|
145
|
+
run: ls -lh dist/
|
|
146
|
+
|
|
147
|
+
- name: Upload .dmg (signed if applicable)
|
|
148
|
+
uses: actions/upload-artifact@v4
|
|
149
|
+
with:
|
|
150
|
+
name: yazses-macos-${{ steps.sign.outputs.sign == 'true' && 'signed' || 'unsigned' }}-${{ github.sha }}
|
|
151
|
+
path: dist/YazSes-*.dmg
|
|
152
|
+
if-no-files-found: error
|
|
153
|
+
retention-days: 14
|
|
154
|
+
|
|
155
|
+
- name: Attach to release (tag builds only)
|
|
156
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
157
|
+
uses: softprops/action-gh-release@v2
|
|
158
|
+
with:
|
|
159
|
+
files: dist/YazSes-*.dmg
|
|
160
|
+
fail_on_unmatched_files: true
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
name: build-windows
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ['v*']
|
|
6
|
+
pull_request:
|
|
7
|
+
paths:
|
|
8
|
+
- 'src/yazses/platform/windows/**'
|
|
9
|
+
- 'src/yazses/__main__.py'
|
|
10
|
+
- 'src/yazses/tray/**'
|
|
11
|
+
- 'packaging/windows/**'
|
|
12
|
+
- 'scripts/build-windows.ps1'
|
|
13
|
+
- '.github/workflows/build-windows.yml'
|
|
14
|
+
- 'pyproject.toml'
|
|
15
|
+
workflow_dispatch:
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
id-token: write # needed by SignPath's OIDC-based authentication
|
|
19
|
+
contents: write # needed by softprops/action-gh-release to attach .exe
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
build:
|
|
23
|
+
runs-on: windows-latest
|
|
24
|
+
timeout-minutes: 30
|
|
25
|
+
|
|
26
|
+
env:
|
|
27
|
+
# SignPath.io signing (free for OSS). All four must be set for the
|
|
28
|
+
# sign step to fire; otherwise the workflow ships an unsigned dev
|
|
29
|
+
# preview (the v0 default).
|
|
30
|
+
# SIGNPATH_API_TOKEN — API token from SignPath account
|
|
31
|
+
# SIGNPATH_ORGANIZATION_ID — UUID of your SignPath organisation
|
|
32
|
+
# SIGNPATH_PROJECT_SLUG — e.g. "yazses"
|
|
33
|
+
# SIGNPATH_SIGNING_POLICY — e.g. "release-signing"
|
|
34
|
+
SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }}
|
|
35
|
+
SIGNPATH_ORGANIZATION_ID: ${{ secrets.SIGNPATH_ORGANIZATION_ID }}
|
|
36
|
+
SIGNPATH_PROJECT_SLUG: ${{ secrets.SIGNPATH_PROJECT_SLUG }}
|
|
37
|
+
SIGNPATH_SIGNING_POLICY: ${{ secrets.SIGNPATH_SIGNING_POLICY }}
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
|
|
42
|
+
- name: Set up uv
|
|
43
|
+
uses: astral-sh/setup-uv@v5
|
|
44
|
+
with:
|
|
45
|
+
version: '0.5.x'
|
|
46
|
+
|
|
47
|
+
- name: Set up Python
|
|
48
|
+
run: uv python install 3.12
|
|
49
|
+
|
|
50
|
+
- name: Confirm Inno Setup is available
|
|
51
|
+
shell: pwsh
|
|
52
|
+
run: |
|
|
53
|
+
$cands = @(
|
|
54
|
+
"${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe",
|
|
55
|
+
"${env:ProgramFiles}\Inno Setup 6\ISCC.exe"
|
|
56
|
+
)
|
|
57
|
+
$iscc = $cands | Where-Object { Test-Path $_ } | Select-Object -First 1
|
|
58
|
+
if (-not $iscc) {
|
|
59
|
+
Write-Host "Inno Setup not preinstalled; installing via choco"
|
|
60
|
+
choco install innosetup -y --no-progress
|
|
61
|
+
} else {
|
|
62
|
+
Write-Host "Found Inno Setup at $iscc"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
- name: Detect signing presence
|
|
66
|
+
id: sign
|
|
67
|
+
shell: pwsh
|
|
68
|
+
run: |
|
|
69
|
+
if ($env:SIGNPATH_API_TOKEN -and $env:SIGNPATH_ORGANIZATION_ID -and $env:SIGNPATH_PROJECT_SLUG -and $env:SIGNPATH_SIGNING_POLICY) {
|
|
70
|
+
Write-Host "Signing via SignPath will run."
|
|
71
|
+
echo "sign=true" >> $env:GITHUB_OUTPUT
|
|
72
|
+
} else {
|
|
73
|
+
Write-Host "SignPath secrets not all present; producing unsigned dev preview."
|
|
74
|
+
echo "sign=false" >> $env:GITHUB_OUTPUT
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
- name: Build installer
|
|
78
|
+
shell: pwsh
|
|
79
|
+
run: ./scripts/build-windows.ps1
|
|
80
|
+
|
|
81
|
+
- name: Locate .exe
|
|
82
|
+
id: locate
|
|
83
|
+
shell: pwsh
|
|
84
|
+
run: |
|
|
85
|
+
$exe = Get-ChildItem "dist\YazSes-*-windows-x64.exe" | Select-Object -First 1
|
|
86
|
+
if (-not $exe) { throw "No installer produced" }
|
|
87
|
+
echo "path=$($exe.FullName)" >> $env:GITHUB_OUTPUT
|
|
88
|
+
echo "name=$($exe.Name)" >> $env:GITHUB_OUTPUT
|
|
89
|
+
|
|
90
|
+
# Upload the unsigned .exe to SignPath, which signs it and returns the
|
|
91
|
+
# signed binary as a separate artefact named "$name.signed".
|
|
92
|
+
- name: Upload to SignPath for signing
|
|
93
|
+
if: steps.sign.outputs.sign == 'true'
|
|
94
|
+
uses: actions/upload-artifact@v4
|
|
95
|
+
with:
|
|
96
|
+
name: unsigned-installer
|
|
97
|
+
path: ${{ steps.locate.outputs.path }}
|
|
98
|
+
if-no-files-found: error
|
|
99
|
+
|
|
100
|
+
- name: Sign with SignPath
|
|
101
|
+
if: steps.sign.outputs.sign == 'true'
|
|
102
|
+
uses: signpath/github-action-submit-signing-request@v1
|
|
103
|
+
with:
|
|
104
|
+
api-token: ${{ env.SIGNPATH_API_TOKEN }}
|
|
105
|
+
organization-id: ${{ env.SIGNPATH_ORGANIZATION_ID }}
|
|
106
|
+
project-slug: ${{ env.SIGNPATH_PROJECT_SLUG }}
|
|
107
|
+
signing-policy-slug: ${{ env.SIGNPATH_SIGNING_POLICY }}
|
|
108
|
+
github-artifact-id: ${{ github.run_id }}
|
|
109
|
+
wait-for-completion: true
|
|
110
|
+
output-artifact-directory: dist-signed
|
|
111
|
+
parameters: |
|
|
112
|
+
Version: ${{ github.ref_name }}
|
|
113
|
+
|
|
114
|
+
- name: Replace unsigned installer with signed one
|
|
115
|
+
if: steps.sign.outputs.sign == 'true'
|
|
116
|
+
shell: pwsh
|
|
117
|
+
run: |
|
|
118
|
+
$signed = Get-ChildItem "dist-signed\*.exe" | Select-Object -First 1
|
|
119
|
+
if (-not $signed) { throw "SignPath returned no signed exe" }
|
|
120
|
+
Copy-Item -Force $signed.FullName "${{ steps.locate.outputs.path }}"
|
|
121
|
+
Write-Host "Replaced unsigned installer with signed version: $($signed.Name)"
|
|
122
|
+
Get-AuthenticodeSignature "${{ steps.locate.outputs.path }}" | Format-List
|
|
123
|
+
|
|
124
|
+
- name: Show build artefacts
|
|
125
|
+
shell: pwsh
|
|
126
|
+
run: Get-ChildItem dist | Format-Table Name, Length, LastWriteTime
|
|
127
|
+
|
|
128
|
+
- name: Upload installer (signed if applicable)
|
|
129
|
+
uses: actions/upload-artifact@v4
|
|
130
|
+
with:
|
|
131
|
+
name: yazses-windows-${{ steps.sign.outputs.sign == 'true' && 'signed' || 'unsigned' }}-${{ github.sha }}
|
|
132
|
+
path: dist/YazSes-*-windows-x64.exe
|
|
133
|
+
if-no-files-found: error
|
|
134
|
+
retention-days: 14
|
|
135
|
+
|
|
136
|
+
- name: Attach to release (tag builds only)
|
|
137
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
138
|
+
uses: softprops/action-gh-release@v2
|
|
139
|
+
with:
|
|
140
|
+
files: dist/YazSes-*-windows-x64.exe
|
|
141
|
+
fail_on_unmatched_files: true
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Launchpad PPA
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
upload-ppa:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
timeout-minutes: 15
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Install Debian packaging tools
|
|
19
|
+
run: |
|
|
20
|
+
sudo apt-get install -y -q devscripts debhelper dput gpg
|
|
21
|
+
|
|
22
|
+
- name: Import GPG key
|
|
23
|
+
uses: crazy-max/ghaction-import-gpg@v6
|
|
24
|
+
with:
|
|
25
|
+
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
|
|
26
|
+
passphrase: ""
|
|
27
|
+
git_user_signingkey: true
|
|
28
|
+
|
|
29
|
+
- name: Configure dput
|
|
30
|
+
run: |
|
|
31
|
+
cat > ~/.dput.cf <<'EOF'
|
|
32
|
+
[yazses-ppa]
|
|
33
|
+
fqdn = ppa.launchpad.net
|
|
34
|
+
method = ftp
|
|
35
|
+
incoming = ~novafabric/ubuntu/yazses/
|
|
36
|
+
login = anonymous
|
|
37
|
+
allow_unsigned_uploads = 0
|
|
38
|
+
EOF
|
|
39
|
+
|
|
40
|
+
- name: Upload to PPA
|
|
41
|
+
env:
|
|
42
|
+
DEBEMAIL: mohsen.seyedkazemi@gmail.com
|
|
43
|
+
DEBFULLNAME: Mohsen Seyedkazemi Moghadam
|
|
44
|
+
GPG_KEY_ID: ${{ secrets.PPA_GPG_KEY_ID }}
|
|
45
|
+
run: |
|
|
46
|
+
VERSION=${GITHUB_REF_NAME#v}
|
|
47
|
+
chmod +x scripts/upload-ppa.sh
|
|
48
|
+
bash scripts/upload-ppa.sh \
|
|
49
|
+
"$VERSION" \
|
|
50
|
+
"$GPG_KEY_ID" \
|
|
51
|
+
"yazses-ppa"
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
test:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Install system dependencies
|
|
21
|
+
run: sudo apt-get install -y libportaudio2
|
|
22
|
+
|
|
23
|
+
- uses: astral-sh/setup-uv@v5
|
|
24
|
+
with:
|
|
25
|
+
version: "latest"
|
|
26
|
+
python-version: "3.12"
|
|
27
|
+
|
|
28
|
+
- run: uv sync
|
|
29
|
+
|
|
30
|
+
- run: uv run pytest tests/ -v
|
|
31
|
+
|
|
32
|
+
publish-pypi:
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
needs: test
|
|
35
|
+
environment: pypi
|
|
36
|
+
permissions:
|
|
37
|
+
id-token: write # required for OIDC trusted publishing
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
|
|
41
|
+
- uses: astral-sh/setup-uv@v5
|
|
42
|
+
with:
|
|
43
|
+
version: "latest"
|
|
44
|
+
python-version: "3.12"
|
|
45
|
+
|
|
46
|
+
- name: Build wheel and sdist
|
|
47
|
+
run: uv build
|
|
48
|
+
|
|
49
|
+
- name: Publish to PyPI
|
|
50
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
51
|
+
|
|
52
|
+
release-linux:
|
|
53
|
+
# Builds the .deb, creates the GitHub Release, and uploads the artifact
|
|
54
|
+
# so the APT repo workflow can download it.
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
needs: test
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@v4
|
|
59
|
+
|
|
60
|
+
- name: Install build tools
|
|
61
|
+
run: sudo apt-get install -y dpkg-dev
|
|
62
|
+
|
|
63
|
+
- name: Build .deb
|
|
64
|
+
run: |
|
|
65
|
+
chmod +x scripts/build-deb.sh
|
|
66
|
+
bash scripts/build-deb.sh
|
|
67
|
+
|
|
68
|
+
- name: Upload .deb artifact
|
|
69
|
+
uses: actions/upload-artifact@v4
|
|
70
|
+
with:
|
|
71
|
+
name: deb-package
|
|
72
|
+
path: "*.deb"
|
|
73
|
+
if-no-files-found: error
|
|
74
|
+
|
|
75
|
+
- name: Create GitHub Release
|
|
76
|
+
uses: softprops/action-gh-release@v2
|
|
77
|
+
with:
|
|
78
|
+
files: "*.deb"
|
|
79
|
+
generate_release_notes: true
|
|
80
|
+
body: |
|
|
81
|
+
Local, offline voice dictation. **Hold a key, speak, release.** No cloud, no GPU.
|
|
82
|
+
|
|
83
|
+
## macOS
|
|
84
|
+
|
|
85
|
+
Download `YazSes-<version>.dmg` from the Assets below, open it, drag
|
|
86
|
+
**YazSes.app** into **Applications**.
|
|
87
|
+
|
|
88
|
+
On first launch, **right-click → Open** (the v0 build is unsigned;
|
|
89
|
+
signing is coming). Grant **Accessibility** + **Microphone** when prompted.
|
|
90
|
+
Default hotkey: **Right Option**. Full guide: `docs/macos-install.md`.
|
|
91
|
+
|
|
92
|
+
## Windows
|
|
93
|
+
|
|
94
|
+
Download `YazSes-<version>-windows-x64.exe` from the Assets and run it.
|
|
95
|
+
|
|
96
|
+
SmartScreen may say *"unrecognized app"* — click **More info → Run anyway**
|
|
97
|
+
(the v0 build is unsigned; signing is coming). Default hotkey: **Right
|
|
98
|
+
Ctrl**. Full guide: `docs/windows-install.md`.
|
|
99
|
+
|
|
100
|
+
## Linux
|
|
101
|
+
|
|
102
|
+
**One-line installer (Debian/Ubuntu):**
|
|
103
|
+
```bash
|
|
104
|
+
bash <(curl -fsSL https://raw.githubusercontent.com/novafabric/yazses/main/install.sh)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**APT repository:**
|
|
108
|
+
```bash
|
|
109
|
+
curl -fsSL https://novafabric.github.io/yazses/apt/KEY.gpg \
|
|
110
|
+
| sudo gpg --dearmor --yes -o /usr/share/keyrings/yazses.gpg
|
|
111
|
+
echo "deb [signed-by=/usr/share/keyrings/yazses.gpg] https://novafabric.github.io/yazses/apt ./" \
|
|
112
|
+
| sudo tee /etc/apt/sources.list.d/yazses.list
|
|
113
|
+
sudo apt update && sudo apt install yazses
|
|
114
|
+
sudo usermod -aG input $USER && logout
|
|
115
|
+
systemctl --user enable --now yazses.service
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Launchpad PPA (Ubuntu):**
|
|
119
|
+
```bash
|
|
120
|
+
sudo add-apt-repository ppa:novafabric/yazses
|
|
121
|
+
sudo apt update && sudo apt install yazses
|
|
122
|
+
sudo usermod -aG input $USER && logout
|
|
123
|
+
systemctl --user enable --now yazses.service
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Snap:**
|
|
127
|
+
```bash
|
|
128
|
+
sudo snap install yazses --classic
|
|
129
|
+
sudo usermod -aG input $USER && logout
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**pipx (any Linux):**
|
|
133
|
+
```bash
|
|
134
|
+
sudo apt install pipx libportaudio2 xdotool xclip
|
|
135
|
+
sudo usermod -aG input $USER && logout
|
|
136
|
+
pipx install yazses && pipx ensurepath
|
|
137
|
+
systemctl --user enable --now yazses.service
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**.deb package:**
|
|
141
|
+
```bash
|
|
142
|
+
sudo apt install ./yazses_*.deb
|
|
143
|
+
sudo usermod -aG input $USER && logout
|
|
144
|
+
systemctl --user enable --now yazses.service
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Default hotkey on Linux: **Space** (configurable). Default config lives
|
|
148
|
+
at `~/.config/yazses/config.toml`.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: Snap
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
version:
|
|
10
|
+
description: "Version to build (without 'v' prefix). Defaults to current snapcraft.yaml value."
|
|
11
|
+
required: false
|
|
12
|
+
type: string
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
snap:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
timeout-minutes: 30
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Set version
|
|
25
|
+
run: |
|
|
26
|
+
if [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${{ inputs.version }}" ]]; then
|
|
27
|
+
VERSION="${{ inputs.version }}"
|
|
28
|
+
elif [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
|
|
29
|
+
VERSION=${GITHUB_REF_NAME#v}
|
|
30
|
+
else
|
|
31
|
+
VERSION=$(grep -E '^version:' snap/snapcraft.yaml | head -1 | sed -E 's/version:\s*"([^"]+)".*/\1/')
|
|
32
|
+
fi
|
|
33
|
+
sed -i "s/^version:.*/version: \"$VERSION\"/" snap/snapcraft.yaml
|
|
34
|
+
echo "Building snap version $VERSION"
|
|
35
|
+
|
|
36
|
+
- name: Build snap
|
|
37
|
+
uses: snapcore/action-build@v1
|
|
38
|
+
id: snap-build
|
|
39
|
+
# Default mode uses an LXD container, which has root and can refresh
|
|
40
|
+
# the apt cache. --destructive-mode runs as the runner user without
|
|
41
|
+
# root, which leaves the package list stale and triggers 404s when
|
|
42
|
+
# Ubuntu rolls forward.
|
|
43
|
+
|
|
44
|
+
- name: Show built artefact
|
|
45
|
+
run: ls -lh "${{ steps.snap-build.outputs.snap }}"
|
|
46
|
+
|
|
47
|
+
- name: Upload .snap as workflow artefact
|
|
48
|
+
uses: actions/upload-artifact@v4
|
|
49
|
+
with:
|
|
50
|
+
name: yazses-snap-${{ github.sha }}
|
|
51
|
+
path: ${{ steps.snap-build.outputs.snap }}
|
|
52
|
+
if-no-files-found: error
|
|
53
|
+
retention-days: 14
|
|
54
|
+
|
|
55
|
+
- name: Check Snap Store credentials presence
|
|
56
|
+
id: check-snap-creds
|
|
57
|
+
env:
|
|
58
|
+
CREDS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
|
59
|
+
run: |
|
|
60
|
+
if [[ -z "${CREDS}" ]]; then
|
|
61
|
+
echo "Snap Store credentials not configured; skipping publish."
|
|
62
|
+
echo "have_creds=false" >> "${GITHUB_OUTPUT}"
|
|
63
|
+
else
|
|
64
|
+
echo "have_creds=true" >> "${GITHUB_OUTPUT}"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
- name: Publish to Snap Store
|
|
68
|
+
if: steps.check-snap-creds.outputs.have_creds == 'true'
|
|
69
|
+
uses: snapcore/action-publish@v1
|
|
70
|
+
env:
|
|
71
|
+
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
|
72
|
+
with:
|
|
73
|
+
snap: ${{ steps.snap-build.outputs.snap }}
|
|
74
|
+
release: stable
|