chore(release): 0.27.1 #68
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| build-sdist: | |
| name: Build sdists | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22 | |
| - name: Build review app frontend | |
| working-directory: web/review-app | |
| run: npm ci && npm run build | |
| - name: Build terminal app frontend | |
| working-directory: web/terminal-app | |
| run: npm ci && npm run build | |
| - name: Build markdown preview app frontend | |
| working-directory: web/markdown-app | |
| run: npm ci && npm run build | |
| - name: Build VNC app frontend | |
| working-directory: web/vnc-app | |
| run: npm ci && npm run build | |
| - name: Build config app frontend | |
| working-directory: web/config-app | |
| run: npm ci && npm run build | |
| - name: Build open-shrimp sdist | |
| run: uv build --sdist | |
| - name: Build moonshine-stt sdist | |
| working-directory: moonshine-stt | |
| run: uv build --sdist | |
| - name: Upload open-shrimp sdist | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: sdist-openshrimp | |
| path: dist/*.tar.gz | |
| - name: Upload moonshine-stt sdist | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: sdist-moonshine-stt | |
| path: moonshine-stt/dist/*.tar.gz | |
| build-binary: | |
| name: Build ${{ matrix.artifact }} | |
| needs: build-sdist | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # open-shrimp | |
| - os: ubuntu-latest | |
| artifact: openshrimp-linux-x86_64 | |
| sdist_artifact: sdist-openshrimp | |
| exec_code: "from open_shrimp.main import main; main()" | |
| features: "libvirt" | |
| - os: ubuntu-24.04-arm | |
| artifact: openshrimp-linux-aarch64 | |
| sdist_artifact: sdist-openshrimp | |
| exec_code: "from open_shrimp.main import main; main()" | |
| features: "libvirt" | |
| - os: macos-latest | |
| artifact: openshrimp-macos-aarch64 | |
| sdist_artifact: sdist-openshrimp | |
| exec_code: "from open_shrimp.main import main; main()" | |
| - os: macos-latest | |
| artifact: openshrimp-macos-x86_64 | |
| sdist_artifact: sdist-openshrimp | |
| exec_code: "from open_shrimp.main import main; main()" | |
| rust_target: x86_64-apple-darwin | |
| # moonshine-stt | |
| - os: ubuntu-latest | |
| artifact: moonshine-stt-linux-x86_64 | |
| sdist_artifact: sdist-moonshine-stt | |
| exec_code: "from moonshine_stt.main import main; main()" | |
| - os: ubuntu-24.04-arm | |
| artifact: moonshine-stt-linux-aarch64 | |
| sdist_artifact: sdist-moonshine-stt | |
| exec_code: "from moonshine_stt.main import main; main()" | |
| - os: macos-latest | |
| artifact: moonshine-stt-macos-aarch64 | |
| sdist_artifact: sdist-moonshine-stt | |
| exec_code: "from moonshine_stt.main import main; main()" | |
| - os: macos-latest | |
| artifact: moonshine-stt-macos-x86_64 | |
| sdist_artifact: sdist-moonshine-stt | |
| exec_code: "from moonshine_stt.main import main; main()" | |
| rust_target: x86_64-apple-darwin | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Download sdist | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: ${{ matrix.sdist_artifact }} | |
| path: dist | |
| - name: Install libvirt development headers | |
| if: matrix.features && contains(matrix.features, 'libvirt') | |
| run: sudo apt-get update && sudo apt-get install -y libvirt-dev | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.rust_target || '' }} | |
| - name: Cache Cargo registry | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| key: ${{ runner.os }}-cargo-pyapp-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: ${{ runner.os }}-cargo-pyapp- | |
| - name: Get sdist filename | |
| id: sdist | |
| run: echo "filename=$(realpath dist/*.tar.gz)" >> "$GITHUB_OUTPUT" | |
| - name: Build with PyApp | |
| env: | |
| PYAPP_PROJECT_PATH: ${{ steps.sdist.outputs.filename }} | |
| PYAPP_PROJECT_FEATURES: ${{ matrix.features || '' }} | |
| PYAPP_PYTHON_VERSION: "3.11" | |
| PYAPP_EXEC_CODE: ${{ matrix.exec_code }} | |
| PYAPP_DISTRIBUTION_EMBED: "1" | |
| PYAPP_PASS_LOCATION: "1" | |
| run: | | |
| if [ -n "${{ matrix.rust_target }}" ]; then | |
| cargo install pyapp --force --root dist/pyapp --target ${{ matrix.rust_target }} | |
| else | |
| cargo install pyapp --force --root dist/pyapp | |
| fi | |
| - name: Rename binary | |
| run: mv dist/pyapp/bin/pyapp dist/${{ matrix.artifact }} | |
| - name: Import signing certificate | |
| if: runner.os == 'macOS' | |
| env: | |
| CERT_B64: ${{ secrets.MACOS_CERTIFICATE_P12_BASE64 }} | |
| CERT_PW: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} | |
| KC_PW: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} | |
| run: | | |
| KC="$RUNNER_TEMP/build.keychain-db" | |
| echo -n "$CERT_B64" | base64 --decode -o "$RUNNER_TEMP/cert.p12" | |
| security create-keychain -p "$KC_PW" "$KC" | |
| security set-keychain-settings -lut 21600 "$KC" | |
| security unlock-keychain -p "$KC_PW" "$KC" | |
| security import "$RUNNER_TEMP/cert.p12" -k "$KC" -P "$CERT_PW" \ | |
| -T /usr/bin/codesign -T /usr/bin/security | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KC_PW" "$KC" | |
| security list-keychains -d user -s "$KC" $(security list-keychains -d user | tr -d '"') | |
| rm "$RUNNER_TEMP/cert.p12" | |
| - name: Sign and notarize binary | |
| if: runner.os == 'macOS' | |
| env: | |
| IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY }} | |
| API_KEY_B64: ${{ secrets.MACOS_NOTARY_API_KEY_P8_BASE64 }} | |
| API_KEY_ID: ${{ secrets.MACOS_NOTARY_API_KEY_ID }} | |
| API_ISSUER_ID: ${{ secrets.MACOS_NOTARY_API_ISSUER_ID }} | |
| run: | | |
| set -e | |
| BIN="dist/${{ matrix.artifact }}" | |
| codesign --force --timestamp --options runtime \ | |
| --entitlements entitlements.plist \ | |
| --sign "$IDENTITY" "$BIN" | |
| codesign --verify --strict --verbose=2 "$BIN" | |
| KEY="$RUNNER_TEMP/notary_key.p8" | |
| echo -n "$API_KEY_B64" | base64 --decode -o "$KEY" | |
| ZIP="$RUNNER_TEMP/${{ matrix.artifact }}.zip" | |
| ditto -c -k --keepParent "$BIN" "$ZIP" | |
| set +e | |
| SUBMIT_OUT=$(xcrun notarytool submit "$ZIP" \ | |
| --key "$KEY" --key-id "$API_KEY_ID" --issuer "$API_ISSUER_ID" \ | |
| --wait --timeout 30m 2>&1) | |
| SUBMIT_RC=$? | |
| echo "$SUBMIT_OUT" | |
| SUBMIT_ID=$(printf '%s\n' "$SUBMIT_OUT" | awk '/^[[:space:]]*id:/ {print $2; exit}') | |
| if [ "$SUBMIT_RC" -ne 0 ] || ! printf '%s\n' "$SUBMIT_OUT" | grep -q 'status: Accepted'; then | |
| if [ -n "$SUBMIT_ID" ]; then | |
| echo "::group::Notary log for $SUBMIT_ID" | |
| xcrun notarytool log "$SUBMIT_ID" \ | |
| --key "$KEY" --key-id "$API_KEY_ID" --issuer "$API_ISSUER_ID" || true | |
| echo "::endgroup::" | |
| fi | |
| rm -f "$ZIP" "$KEY" | |
| exit 1 | |
| fi | |
| # Single-file binaries can't be stapled; Gatekeeper checks online. | |
| rm "$ZIP" "$KEY" | |
| - name: Upload binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: dist/${{ matrix.artifact }} | |
| build-virtiofsd: | |
| name: Build virtiofsd (${{ matrix.arch }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| arch: x86_64 | |
| artifact: virtiofsd-linux-x86_64 | |
| - os: ubuntu-24.04-arm | |
| arch: aarch64 | |
| artifact: virtiofsd-linux-aarch64 | |
| steps: | |
| - name: Install system build dependencies | |
| run: sudo apt-get update && sudo apt-get install -y libseccomp-dev libcap-ng-dev | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Cargo registry | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| key: ${{ runner.os }}-${{ runner.arch }}-cargo-virtiofsd-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: ${{ runner.os }}-${{ runner.arch }}-cargo-virtiofsd- | |
| - name: Clone virtiofsd | |
| run: git clone --depth 1 --branch v1.13.3 https://gitlab.com/virtio-fs/virtiofsd.git | |
| - name: Build virtiofsd | |
| working-directory: virtiofsd | |
| run: cargo build --release | |
| - name: Rename binary | |
| run: mv virtiofsd/target/release/virtiofsd ${{ matrix.artifact }} | |
| - name: Upload binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: ${{ matrix.artifact }} | |
| build-macos-app: | |
| name: Build macOS .app | |
| needs: build-sdist | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22 | |
| - name: Build review app frontend | |
| working-directory: web/review-app | |
| run: npm ci && npm run build | |
| - name: Build terminal app frontend | |
| working-directory: web/terminal-app | |
| run: npm ci && npm run build | |
| - name: Build markdown preview app frontend | |
| working-directory: web/markdown-app | |
| run: npm ci && npm run build | |
| - name: Build VNC app frontend | |
| working-directory: web/vnc-app | |
| run: npm ci && npm run build | |
| - name: Build config app frontend | |
| working-directory: web/config-app | |
| run: npm ci && npm run build | |
| - name: Install dependencies | |
| run: | | |
| uv pip install --system py2app setuptools | |
| uv pip install --system '.[macos]' | |
| - name: Build .app bundle | |
| run: | | |
| # ruamel is a PEP 420 namespace package (no __init__.py), which | |
| # py2app's imp.find_module cannot resolve. Add a stub so py2app | |
| # can locate the package. | |
| touch "$(python -c 'import ruamel; print(ruamel.__path__[0])')/__init__.py" | |
| mv pyproject.toml pyproject.toml.bak | |
| python setup_app.py py2app | |
| mv pyproject.toml.bak pyproject.toml | |
| - name: Import signing certificate | |
| env: | |
| CERT_B64: ${{ secrets.MACOS_CERTIFICATE_P12_BASE64 }} | |
| CERT_PW: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} | |
| KC_PW: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} | |
| run: | | |
| KC="$RUNNER_TEMP/build.keychain-db" | |
| echo -n "$CERT_B64" | base64 --decode -o "$RUNNER_TEMP/cert.p12" | |
| security create-keychain -p "$KC_PW" "$KC" | |
| security set-keychain-settings -lut 21600 "$KC" | |
| security unlock-keychain -p "$KC_PW" "$KC" | |
| security import "$RUNNER_TEMP/cert.p12" -k "$KC" -P "$CERT_PW" \ | |
| -T /usr/bin/codesign -T /usr/bin/security | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KC_PW" "$KC" | |
| security list-keychains -d user -s "$KC" $(security list-keychains -d user | tr -d '"') | |
| rm "$RUNNER_TEMP/cert.p12" | |
| - name: Sign .app bundle | |
| env: | |
| IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY }} | |
| run: | | |
| set -e | |
| APP="dist/OpenShrimp.app" | |
| # Sign every Mach-O file inside the bundle. Extension-based matching | |
| # isn't enough for py2app (the embedded Python interpreter has no | |
| # suffix), so probe each file with `file`. | |
| find "$APP" -type f | while read -r f; do | |
| if file -b "$f" | grep -qE 'Mach-O|dynamically linked shared library'; then | |
| codesign --force --timestamp --options runtime \ | |
| --sign "$IDENTITY" "$f" | |
| fi | |
| done | |
| # Sign embedded bundles (frameworks, nested .app) deepest-first so | |
| # each enclosing CodeResources seal covers already-signed contents. | |
| find "$APP/Contents" -type d \( -name "*.framework" -o -name "*.app" \) | \ | |
| awk -F/ '{ print NF, $0 }' | sort -k1 -rn | cut -d' ' -f2- | \ | |
| while read -r b; do | |
| codesign --force --timestamp --options runtime \ | |
| --sign "$IDENTITY" "$b" | |
| done | |
| # Finally sign the outer bundle with entitlements. | |
| codesign --force --timestamp --options runtime \ | |
| --entitlements entitlements.plist \ | |
| --sign "$IDENTITY" "$APP" | |
| codesign --verify --strict --deep --verbose=2 "$APP" | |
| - name: Create DMG | |
| run: | | |
| brew install create-dmg | |
| create-dmg \ | |
| --volname "OpenShrimp" \ | |
| --window-size 600 400 \ | |
| --icon "OpenShrimp.app" 150 200 \ | |
| --app-drop-link 450 200 \ | |
| --no-internet-enable \ | |
| "dist/OpenShrimp-$(cat VERSION).dmg" \ | |
| "dist/OpenShrimp.app" | |
| - name: Sign, notarize, and staple DMG | |
| env: | |
| IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY }} | |
| API_KEY_B64: ${{ secrets.MACOS_NOTARY_API_KEY_P8_BASE64 }} | |
| API_KEY_ID: ${{ secrets.MACOS_NOTARY_API_KEY_ID }} | |
| API_ISSUER_ID: ${{ secrets.MACOS_NOTARY_API_ISSUER_ID }} | |
| run: | | |
| set -e | |
| DMG="dist/OpenShrimp-$(cat VERSION).dmg" | |
| codesign --force --timestamp --sign "$IDENTITY" "$DMG" | |
| KEY="$RUNNER_TEMP/notary_key.p8" | |
| echo -n "$API_KEY_B64" | base64 --decode -o "$KEY" | |
| set +e | |
| SUBMIT_OUT=$(xcrun notarytool submit "$DMG" \ | |
| --key "$KEY" --key-id "$API_KEY_ID" --issuer "$API_ISSUER_ID" \ | |
| --wait --timeout 30m 2>&1) | |
| SUBMIT_RC=$? | |
| echo "$SUBMIT_OUT" | |
| SUBMIT_ID=$(printf '%s\n' "$SUBMIT_OUT" | awk '/^[[:space:]]*id:/ {print $2; exit}') | |
| if [ "$SUBMIT_RC" -ne 0 ] || ! printf '%s\n' "$SUBMIT_OUT" | grep -q 'status: Accepted'; then | |
| if [ -n "$SUBMIT_ID" ]; then | |
| echo "::group::Notary log for $SUBMIT_ID" | |
| xcrun notarytool log "$SUBMIT_ID" \ | |
| --key "$KEY" --key-id "$API_KEY_ID" --issuer "$API_ISSUER_ID" || true | |
| echo "::endgroup::" | |
| fi | |
| rm -f "$KEY" | |
| exit 1 | |
| fi | |
| rm "$KEY" | |
| xcrun stapler staple "$DMG" | |
| xcrun stapler validate "$DMG" | |
| - name: Upload DMG | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: OpenShrimp-macos-app | |
| path: dist/OpenShrimp-*.dmg | |
| release: | |
| name: Create GitHub Release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| needs: [build-binary, build-virtiofsd, build-macos-app] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: artifacts | |
| merge-multiple: true | |
| - name: Create release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| generate_release_notes: true | |
| files: | | |
| artifacts/openshrimp-* | |
| artifacts/moonshine-stt-* | |
| artifacts/virtiofsd-* | |
| artifacts/OpenShrimp-*.dmg | |
| artifacts/*.tar.gz |