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
70 changes: 70 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: CI

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
test-windows:
name: Tests (Windows)
runs-on: windows-latest

steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Set up Python 3.12
uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Run test suite
run: python run_tests.py

test-linux:
name: Tests (Linux)
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Install PortAudio, Tkinter and a virtual display
run: |
sudo apt-get update
sudo apt-get install -y portaudio19-dev python3-tk xvfb

- name: Set up Python 3.12
uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

# Guards the exact regression that shipped two broken release assets:
# ui/app.py used to import pyaudiowpatch unconditionally, which only
# exists on Windows, and Pillow was missing from requirements.txt. Both
# blow up at import time, long before any test asserts anything - and no
# test imports this module unless a display is available.
- name: Import check (non-Windows startup path)
run: python -c "import audio_transcriber.ui.app; print('ui.app imports cleanly')"

# xvfb so the GUI smoke test actually runs instead of skipping itself.
- name: Run test suite
run: xvfb-run -a python run_tests.py
154 changes: 84 additions & 70 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,58 @@ permissions:
contents: write

jobs:
# Resolve the release version once so every job and every archive name agrees.
# A tag push uses the tag; a manual dispatch produces a dev version.
version:
name: Resolve Release Version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.resolve.outputs.version }}
steps:
- name: Resolve version from tag or dispatch
id: resolve
run: |
if [ "${{ github.ref_type }}" = "tag" ]; then
VERSION="${{ github.ref_name }}"
else
VERSION="v0.0.0-dev+${GITHUB_SHA::7}"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Release version: $VERSION"

test:
name: Run Test Suite
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Set up Python 3.12
uses: actions/setup-python@v7
with:
python-version: "3.12"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Run tests
run: python run_tests.py

build-windows:
name: Build Windows x64 Standalone Package
runs-on: windows-latest
needs: [version, test]
env:
RELEASE_VERSION: ${{ needs.version.outputs.version }}

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Set up Python 3.12
uses: actions/setup-python@v5
uses: actions/setup-python@v7
with:
python-version: "3.12"

Expand All @@ -30,151 +72,123 @@ jobs:
pip install pyinstaller

- name: Build Windows executable & zip package
run: |
python build_release.py
run: python build_release.py

- name: Upload Windows Build Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: windows-release-package
path: dist/AudioTranscriber-*-windows-x64.zip

build-linux:
name: Build Linux x64 Standalone Package
runs-on: ubuntu-latest
needs: [version, test]
env:
RELEASE_VERSION: ${{ needs.version.outputs.version }}

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Install Linux system audio dependencies & Tkinter
run: |
sudo apt-get update
sudo apt-get install -y portaudio19-dev python3-tk libasound2-dev libjack-jackd2-dev

- name: Set up Python 3.12
uses: actions/setup-python@v5
uses: actions/setup-python@v7
with:
python-version: "3.12"

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install PyAudio soundfile scipy numpy pyinstaller
pip install -r requirements.txt
pip install pyinstaller

- name: Build Linux executable & tar.gz package
run: |
pyinstaller --name AudioTranscriber --windowed --onedir --noconfirm --clean \
--collect-all soundfile \
--hidden-import scipy.signal \
--exclude-module torch \
--exclude-module torchvision \
--exclude-module torchaudio \
--exclude-module pandas \
--exclude-module sklearn \
--exclude-module matplotlib \
--exclude-module pyarrow \
main.py

cd dist
tar -czvf AudioTranscriber-v1.0.0-linux-x64.tar.gz AudioTranscriber
run: python build_release.py

- name: Upload Linux Build Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: linux-release-package
path: dist/AudioTranscriber-*-linux-x64.tar.gz

build-macos:
name: Build macOS Standalone Package
runs-on: macos-latest
needs: [version, test]
env:
RELEASE_VERSION: ${{ needs.version.outputs.version }}

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Install PortAudio via Homebrew
run: |
brew install portaudio
run: brew install portaudio

- name: Set up Python 3.12
uses: actions/setup-python@v5
uses: actions/setup-python@v7
with:
python-version: "3.12"

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install PyAudio soundfile scipy numpy pyinstaller
pip install -r requirements.txt
pip install pyinstaller

- name: Build macOS app bundle & zip package
run: |
pyinstaller --name AudioTranscriber --windowed --onedir --noconfirm --clean \
--collect-all soundfile \
--hidden-import scipy.signal \
--exclude-module torch \
--exclude-module torchvision \
--exclude-module torchaudio \
--exclude-module pandas \
--exclude-module sklearn \
--exclude-module matplotlib \
--exclude-module pyarrow \
main.py

cd dist
zip -r AudioTranscriber-v1.0.0-macos-universal.zip AudioTranscriber.app || zip -r AudioTranscriber-v1.0.0-macos-universal.zip AudioTranscriber
run: python build_release.py

- name: Upload macOS Build Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: macos-release-package
path: dist/AudioTranscriber-*-macos-universal.zip
path: dist/AudioTranscriber-*-macos-*.zip

publish-release:
name: Publish GitHub Release with Multi-Platform Assets
needs: [build-windows, build-linux, build-macos]
needs: [version, build-windows, build-linux, build-macos]
if: github.ref_type == 'tag'
runs-on: ubuntu-latest
env:
RELEASE_VERSION: ${{ needs.version.outputs.version }}

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Download Windows Release Asset
uses: actions/download-artifact@v4
- name: Download all release assets
uses: actions/download-artifact@v8
with:
name: windows-release-package
pattern: "*-release-package"
merge-multiple: true
path: release-assets/

- name: Download Linux Release Asset
uses: actions/download-artifact@v4
with:
name: linux-release-package
path: release-assets/

- name: Download macOS Release Asset
uses: actions/download-artifact@v4
with:
name: macos-release-package
path: release-assets/
- name: List collected assets
run: ls -lh release-assets/

- name: Create or Update GitHub Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
files: release-assets/*
name: Audio AI Recorder & Transcriber ${{ github.ref_name }}
name: Audio AI Recorder & Transcriber ${{ env.RELEASE_VERSION }}
body: |
## 🚀 Multi-Platform Standalone Release (${{ github.ref_name }})
## 🚀 Multi-Platform Standalone Release (${{ env.RELEASE_VERSION }})

### 💻 Downloads
- **Windows (x64)**: `AudioTranscriber-${{ github.ref_name }}-windows-x64.zip`
- **Linux (x64)**: `AudioTranscriber-${{ github.ref_name }}-linux-x64.tar.gz`
- **macOS (Intel & Apple Silicon)**: `AudioTranscriber-${{ github.ref_name }}-macos-universal.zip`
- **Windows (x64)**: `AudioTranscriber-${{ env.RELEASE_VERSION }}-windows-x64.zip`
- **Linux (x64)**: `AudioTranscriber-${{ env.RELEASE_VERSION }}-linux-x64.tar.gz`
- **macOS (Apple Silicon)**: `AudioTranscriber-${{ env.RELEASE_VERSION }}-macos-arm64.zip`

### 📖 Quick Start
1. Download the appropriate package for your operating system.
2. Extract the archive to any directory.
3. Run `AudioTranscriber.exe` (Windows), `./AudioTranscriber` (Linux), or open `AudioTranscriber.app` (macOS).

> 🍎 **Intel Macs**: this build is Apple Silicon only. Run from source or build locally with `python build_release.py` to get a `macos-x64` archive.

> 🎧 **macOS Note**: System audio recording on macOS requires a virtual loopback device like [BlackHole](https://github.com/ExistentialAudio/BlackHole) (Free & Open Source).
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,3 @@ venv/
.pytest_cache/
.coverage
htmlcov/
tests/
run_tests.py
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ An advanced, privacy-focused audio recording and AI transcription suite. It capt
No Python installation or terminal setup required!

1. Download the latest release package for your operating system from the **[Releases Page](https://github.com/SecretLUL/Audio-Transcriber/releases)**:
- **Windows**: `AudioTranscriber-v1.0.2-windows-x64.zip`
- **Linux**: `AudioTranscriber-v1.0.2-linux-x64.tar.gz`
- **macOS**: `AudioTranscriber-v1.0.2-macos-universal.zip`
- **Windows (x64)**: `AudioTranscriber-<version>-windows-x64.zip`
- **Linux (x64)**: `AudioTranscriber-<version>-linux-x64.tar.gz`
- **macOS (Apple Silicon)**: `AudioTranscriber-<version>-macos-arm64.zip`
2. Extract the archive to any folder.
3. Launch `AudioTranscriber.exe` (Windows), `./AudioTranscriber` (Linux), or `AudioTranscriber.app` (macOS).

> 🍎 **Intel Macs**: the released macOS build is Apple Silicon only. On an Intel
> Mac, run from source (Option B) or build locally with `python build_release.py`,
> which produces a `macos-x64` archive.

---

### Option B: Running from Source (For Developers 🛠️)
Expand Down Expand Up @@ -94,7 +98,7 @@ Audio-Transcriber/
├── main.py Entry point for python / pythonw launch
├── Start-Recorder.vbs Windows double-click launcher
├── build_release.py Automated PyInstaller standalone build & zip packaging
├── requirements.txt Core dependencies (pyaudiowpatch, soundfile, scipy, numpy)
├── requirements.txt Core dependencies (pyaudiowpatch, soundfile, scipy, numpy, Pillow)
├── LICENSE MIT License (100% FOSS)
├── README.md Project documentation
├── audio_transcriber/ Main application package
Expand Down Expand Up @@ -180,13 +184,26 @@ python run_tests.py

## 📦 Automated Release Build

To build a standalone executable and zip archive locally using PyInstaller:
To build a standalone executable and release archive locally using PyInstaller:

```shell
python build_release.py
```

The output executable and `.zip` package will be saved in the `dist/` directory.
The build runs on Windows, Linux and macOS and names the archive after the
current platform and version, e.g. `AudioTranscriber-v1.2.0-windows-x64.zip`.

The version is resolved in this order:

1. An explicit argument — `python build_release.py v1.2.0`
2. The `RELEASE_VERSION` environment variable (the CI sets this from the tag)
3. The git tag pointing at `HEAD`
4. `v0.0.0-dev` as a fallback

Before archiving, the script verifies that every module the app imports at
startup actually made it into the bundle and fails the build otherwise.

The output executable and archive are saved in the `dist/` directory.

---

Expand Down
Loading
Loading