improve: rework VoiceModel
#2545
Workflow file for this run
This file contains 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: build and deploy workflow | |
# 製品版もビルドできる。製品版ビルド時の違いは以下の3点 | |
# 1. production環境を使う | |
# 2. 製品版リポジトリのコードをmergeする | |
# 3. RESOURCEリポジトリからモデルをダウンロードして置き換える | |
on: | |
workflow_dispatch: | |
inputs: | |
version: | |
description: "バージョン情報(A.BB.C / A.BB.C-preview.D)" | |
required: true | |
code_signing: | |
description: "コード署名する" | |
type: boolean | |
required: false | |
default: false | |
is_production: | |
description: "製品版をビルドする" | |
type: boolean | |
required: false | |
default: false | |
release: | |
types: | |
- published | |
pull_request: | |
push: | |
env: | |
VOICEVOX_RESOURCE_VERSION: "0.15.0-preview.3" | |
VOICEVOX_FAT_RESOURCE_VERSION: "0.15.0-preview.4" | |
# releaseタグ名か、workflow_dispatchでのバージョン名か、'0.0.0'が入る | |
VERSION: ${{ github.event.release.tag_name || inputs.version || '0.0.0' }} | |
PRODUCTION_REPOSITORY_TAG: "0.15.0-preview.2" # 製品版のタグ名 | |
# 簡易テストとするかどうか。releaseとworkflow_dispatch以外は簡易テストとする | |
IS_SIMPLE_TEST: ${{ github.event_name != 'release' && github.event_name != 'workflow_dispatch' }} | |
defaults: | |
run: | |
shell: bash | |
jobs: | |
# 全 jobs で利用する定数の定義。実行対象の条件をフィルタリングする。 | |
# | |
# c_release_format = plain-cdylib | ios-xcframework | |
# | |
# `plain-cdylib`の場合、動的ライブラリとその付属物をZIPに固めたものをC APIとしてリリースする。 | |
# `ios-xcframework`の場合はiOS用のXCFrameworkをC APIとしてリリースする。また、ONNX Runtimeの | |
# リンク方法に関わるCargoフィーチャも`c_release_format`によって選択される。 | |
config: | |
runs-on: ubuntu-latest | |
outputs: | |
includes: ${{ steps.strategy_matrix.outputs.includes }} | |
deploy: ${{ env.VERSION != '0.0.0' }} | |
version: ${{ env.VERSION }} | |
steps: | |
- name: declare strategy matrix | |
id: strategy_matrix | |
run: | | |
includes='[ | |
{ | |
"os": "windows-2019", | |
"target": "x86_64-pc-windows-msvc", | |
"artifact_name": "windows-x64", | |
"c_release_format": "plain-cdylib", | |
"python_whl": true, | |
"can_skip_in_simple_test": false | |
}, | |
{ | |
"os": "windows-2019", | |
"target": "i686-pc-windows-msvc", | |
"artifact_name": "windows-x86", | |
"c_release_format": "plain-cdylib", | |
"python_whl": true, | |
"can_skip_in_simple_test": true | |
}, | |
{ | |
"os": "ubuntu-20.04", | |
"target": "x86_64-unknown-linux-gnu", | |
"artifact_name": "linux-x64", | |
"c_release_format": "plain-cdylib", | |
"python_whl": true, | |
"can_skip_in_simple_test": false | |
}, | |
{ | |
"os": "ubuntu-20.04", | |
"target": "aarch64-unknown-linux-gnu", | |
"artifact_name": "linux-arm64", | |
"c_release_format": "plain-cdylib", | |
"python_whl": true, | |
"can_skip_in_simple_test": true | |
}, | |
{ | |
"os": "ubuntu-20.04", | |
"target": "aarch64-linux-android", | |
"artifact_name": "android-arm64", | |
"c_release_format": "plain-cdylib", | |
"python_whl": false, | |
"can_skip_in_simple_test": true | |
}, | |
{ | |
"os": "ubuntu-20.04", | |
"target": "x86_64-linux-android", | |
"artifact_name": "android-x86_64", | |
"c_release_format": "plain-cdylib", | |
"python_whl": false, | |
"can_skip_in_simple_test": true | |
}, | |
{ | |
"os": "macos-12", | |
"target": "aarch64-apple-darwin", | |
"artifact_name": "osx-arm64", | |
"c_release_format": "plain-cdylib", | |
"python_whl": true, | |
"can_skip_in_simple_test": false | |
}, | |
{ | |
"os": "macos-12", | |
"target": "x86_64-apple-darwin", | |
"artifact_name": "osx-x64", | |
"c_release_format": "plain-cdylib", | |
"python_whl": true, | |
"can_skip_in_simple_test": true | |
}, | |
{ | |
"os": "macos-12", | |
"target": "aarch64-apple-ios", | |
"artifact_name": "ios-arm64-cpu", | |
"c_release_format": "ios-xcframework", | |
"python_whl": false, | |
"can_skip_in_simple_test": true | |
}, | |
{ | |
"os": "macos-12", | |
"target": "aarch64-apple-ios-sim", | |
"artifact_name": "ios-arm64-cpu-sim", | |
"c_release_format": "ios-xcframework", | |
"python_whl": false, | |
"can_skip_in_simple_test": true | |
}, | |
{ | |
"os": "macos-12", | |
"target": "x86_64-apple-ios", | |
"artifact_name": "ios-x64-cpu", | |
"c_release_format": "ios-xcframework", | |
"python_whl": false, | |
"can_skip_in_simple_test": true | |
} | |
]' | |
# FIXME: composite action に切り出す | |
if ${{ env.IS_SIMPLE_TEST }}; then | |
includes=$(echo "$includes" | jq -c '[.[] | select(.can_skip_in_simple_test == false)]') | |
fi | |
includes=$(echo "$includes" | jq -c '[.[] | del(.can_skip_in_simple_test)]') | |
echo "includes=${includes}" >> "$GITHUB_OUTPUT" | |
build_and_deploy: | |
needs: config | |
environment: ${{ inputs.is_production && 'production' || '' }} # 製品版のenvironment | |
strategy: | |
matrix: | |
include: ${{ fromJson(needs.config.outputs.includes) }} | |
runs-on: ${{ matrix.os }} | |
env: | |
ASSET_NAME: voicevox_core-${{ matrix.artifact_name }}-${{ needs.config.outputs.version }} | |
steps: | |
- uses: actions/checkout@v4 # 製品版ではない場合 | |
if: ${{ !inputs.is_production }} | |
- uses: actions/checkout@v4 # 製品版の場合 | |
if: inputs.is_production | |
with: | |
fetch-depth: 0 # 全履歴取得 | |
token: ${{ secrets.PRODUCTION_GITHUB_TOKEN }} | |
- name: Merge production branch | |
if: inputs.is_production | |
shell: bash | |
run: | | |
( | |
git remote add private ${{ secrets.PRODUCTION_REPOSITORY_URL }} | |
git fetch private refs/tags/${{ env.PRODUCTION_REPOSITORY_TAG }} | |
git -c user.name=dummy -c [email protected] merge FETCH_HEAD | |
) > /dev/null 2>&1 | |
- name: Set up Python 3.8 | |
if: matrix.python_whl | |
uses: actions/setup-python@v5 | |
with: | |
python-version: "3.8" | |
architecture: ${{ contains(matrix.artifact_name,'x86') && 'x86' || 'x64' }} | |
- name: set up ${{ matrix.target }} | |
uses: ./.github/actions/rust-toolchain-from-file | |
with: | |
targets: ${{ matrix.target }} | |
- name: Install cross compiler for aarch64-unknown-linux-gnu | |
if: matrix.target == 'aarch64-unknown-linux-gnu' | |
run: | | |
sudo apt update | |
sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu | |
- uses: nttld/setup-ndk@v1 | |
if: endsWith(matrix.target, '-linux-android') | |
with: | |
ndk-version: r25b | |
- name: Set path for android | |
if: endsWith(matrix.target, '-linux-android') | |
run: | | |
echo "$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin" >> "$GITHUB_PATH" | |
echo "AR_${{ matrix.target }}=llvm-ar" >> "$GITHUB_ENV" | |
- name: Checkout VOICEVOX RESOURCE | |
if: inputs.is_production | |
uses: actions/checkout@v4 | |
with: | |
repository: VOICEVOX/voicevox_resource | |
ref: ${{ env.VOICEVOX_RESOURCE_VERSION }} | |
path: download/resource | |
- name: Raplace resource | |
if: inputs.is_production | |
shell: bash | |
run: | |
mv -f download/resource/core/README.md ./README.md | |
- name: Install cargo-binstall | |
uses: taiki-e/install-action@cargo-binstall | |
- name: Install cargo-edit | |
run: cargo binstall cargo-edit@^0.11 --no-confirm --log-level debug | |
- name: set cargo version | |
run: | | |
cargo set-version "$VERSION" --exclude voicevox_core_python_api --exclude downloader --exclude xtask | |
if ${{ matrix.python_whl }}; then cargo set-version "$VERSION" -p voicevox_core_python_api; fi | |
- name: cache target | |
uses: Swatinem/rust-cache@v2 | |
if: ${{ !inputs.is_production }} | |
- name: build voicevox_core_c_api | |
shell: bash | |
run: | | |
case ${{ matrix.c_release_format }} in | |
plain-cdylib) linking=load-onnxruntime ;; | |
ios-xcframework) linking=link-onnxruntime ;; | |
esac | |
function build() { | |
cargo build -p voicevox_core_c_api -vv --features "$linking" --target ${{ matrix.target }} --release | |
} | |
if ${{ !inputs.is_production }}; then | |
build | |
else | |
build > /dev/null 2>&1 | |
fi | |
env: | |
RUSTFLAGS: -C panic=abort | |
- name: build voicevox_core_python_api | |
if: matrix.python_whl | |
id: build-voicevox-core-python-api | |
run: | | |
rm -rf ./target/wheels | |
pip install --upgrade poetry | |
poetry config virtualenvs.create false | |
(cd crates/voicevox_core_python_api && poetry install --with dev) | |
function build() { | |
maturin build --manifest-path ./crates/voicevox_core_python_api/Cargo.toml --target ${{ matrix.target }} --release | |
} | |
if ${{ !inputs.is_production }}; then | |
build | |
else | |
build > /dev/null 2>&1 | |
fi | |
echo "whl=$(find ./target/wheels -type f)" >> "$GITHUB_OUTPUT" | |
- name: build voicevox_core_java_api | |
if: contains(matrix.target, 'android') | |
run: | | |
function build() { | |
cargo build -p voicevox_core_java_api -vv --target ${{ matrix.target }} --release | |
} | |
if ${{ !inputs.is_production }}; then | |
build | |
else | |
build > /dev/null 2>&1 | |
fi | |
- name: Organize artifact | |
run: | | |
mkdir -p "artifact/${{ env.ASSET_NAME }}" | |
case ${{ matrix.c_release_format }} in | |
plain-cdylib) feature=VOICEVOX_LOAD_ONNXRUNTIME ;; | |
ios-xcframework) feature=VOICEVOX_LINK_ONNXRUNTIME ;; | |
esac | |
sed 's:^//\(#define '"$feature"'\)$:\1:' crates/voicevox_core_c_api/include/voicevox_core.h \ | |
> "artifact/${{ env.ASSET_NAME }}/voicevox_core.h" | |
cp -v target/${{ matrix.target }}/release/*voicevox_core.{dll,so,dylib} "artifact/${{ env.ASSET_NAME }}" || true | |
cp -v target/${{ matrix.target }}/release/voicevox_core.dll.lib "artifact/${{ env.ASSET_NAME }}/voicevox_core.lib" || true | |
cp -v README.md "artifact/${{ env.ASSET_NAME }}/README.txt" | |
echo "${{ env.VERSION }}" > "artifact/${{ env.ASSET_NAME }}/VERSION" | |
mkdir java_artifact | |
cp -v target/${{ matrix.target }}/release/libvoicevox_core_java_api.so java_artifact/ || true | |
- name: Code signing (Windows) | |
if: startsWith(matrix.os, 'windows') && inputs.code_signing | |
run: | |
bash build_util/codesign.bash "artifact/${{ env.ASSET_NAME }}/voicevox_core.dll" | |
env: | |
ESIGNERCKA_USERNAME: ${{ secrets.ESIGNERCKA_USERNAME }} | |
ESIGNERCKA_PASSWORD: ${{ secrets.ESIGNERCKA_PASSWORD }} | |
ESIGNERCKA_TOTP_SECRET: ${{ secrets.ESIGNERCKA_TOTP_SECRET }} | |
- name: Upload artifact to build XCFramework | |
if: matrix.c_release_format == 'ios-xcframework' | |
uses: actions/upload-artifact@v4 | |
with: | |
name: voicevox_core-${{ matrix.target }} | |
path: artifact/${{ env.ASSET_NAME }} | |
- name: Archive artifact | |
run: | | |
cd artifact | |
7z a "../${{ env.ASSET_NAME }}.zip" "${{ env.ASSET_NAME }}" | |
- name: Upload to Release | |
if: fromJson(needs.config.outputs.deploy) && matrix.c_release_format == 'plain-cdylib' | |
uses: softprops/action-gh-release@v2 | |
with: | |
prerelease: true | |
tag_name: ${{ env.VERSION }} | |
files: |- | |
${{ env.ASSET_NAME }}.zip | |
target_commitish: ${{ github.sha }} | |
- name: Upload Python whl to Release | |
if: fromJson(needs.config.outputs.deploy) && matrix.python_whl | |
uses: softprops/action-gh-release@v2 | |
with: | |
prerelease: true | |
tag_name: ${{ env.VERSION }} | |
files: |- | |
${{ steps.build-voicevox-core-python-api.outputs.whl }} | |
target_commitish: ${{ github.sha }} | |
- name: Upload voicevox_core_java_api artifact | |
if: fromJson(needs.config.outputs.deploy) && contains(matrix.target, 'android') | |
uses: actions/upload-artifact@v4 | |
with: | |
name: voicevox_core_java_api-${{ matrix.artifact_name }} | |
path: java_artifact | |
build_xcframework: | |
if: ${{ !(github.event_name != 'release' && github.event_name != 'workflow_dispatch') }} # !env.IS_SIMPLE_TEST と同じ | |
needs: [config, build_and_deploy] | |
runs-on: macos-12 | |
env: | |
IOS_X86_64_PATH: artifact/voicevox_core-x86_64-apple-ios | |
IOS_AARCH64_SIM_PATH: artifact/voicevox_core-aarch64-apple-ios-sim | |
IOS_AARCH64_PATH: artifact/voicevox_core-aarch64-apple-ios | |
ASSET_NAME: voicevox_core-ios-xcframework-cpu-${{ needs.config.outputs.version }} | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/download-artifact@v4 | |
with: | |
name: voicevox_core-x86_64-apple-ios | |
path: ${{ env.IOS_X86_64_PATH }} | |
- uses: actions/download-artifact@v4 | |
with: | |
name: voicevox_core-aarch64-apple-ios-sim | |
path: ${{ env.IOS_AARCH64_SIM_PATH }} | |
- uses: actions/download-artifact@v4 | |
with: | |
name: voicevox_core-aarch64-apple-ios | |
path: ${{ env.IOS_AARCH64_PATH }} | |
- name: Create xcframework | |
id: create-xcframework | |
run: | | |
build_util/make_ios_xcframework.bash | |
echo "output_asset_path=${OUTPUT_ASSET_PATH}" >> "$GITHUB_OUTPUT" | |
env: | |
OUTPUT_ASSET_PATH: artifact/voicevox_core-ios-xcframework-cpu | |
- name: Archive artifact | |
run: | | |
cd ${{ steps.create-xcframework.outputs.output_asset_path }} | |
7z a "../../${{ env.ASSET_NAME }}.zip" "voicevox_core.xcframework" | |
- name: Upload to Release | |
if: fromJson(needs.config.outputs.deploy) | |
uses: softprops/action-gh-release@v2 | |
with: | |
prerelease: true | |
tag_name: ${{ env.VERSION }} | |
files: |- | |
${{ env.ASSET_NAME }}.zip | |
target_commitish: ${{ github.sha }} | |
deploy_model: | |
runs-on: ubuntu-latest | |
needs: config | |
env: | |
ASSET_NAME: model-${{ needs.config.outputs.version }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Checkout VOICEVOX FAT RESOURCE | |
if: inputs.is_production | |
uses: actions/checkout@v4 | |
with: | |
repository: VOICEVOX/voicevox_fat_resource | |
ref: ${{ env.VOICEVOX_FAT_RESOURCE_VERSION }} | |
path: download/fat_resource | |
- name: Raplace resource | |
if: inputs.is_production | |
shell: bash | |
run: | |
rm -r ./model; mv download/fat_resource/core/model ./model | |
- name: Create artifact | |
run: | | |
mkdir "artifact" | |
mv model "artifact/${{ env.ASSET_NAME }}/" | |
- name: Archive artifact | |
run: | | |
cd artifact | |
7z a "../${{ env.ASSET_NAME }}.zip" "${{ env.ASSET_NAME }}" | |
- name: Upload to Release | |
if: fromJson(needs.config.outputs.deploy) | |
uses: softprops/action-gh-release@v2 | |
with: | |
prerelease: true | |
tag_name: ${{ env.VERSION }} | |
files: |- | |
${{ env.ASSET_NAME }}.zip | |
target_commitish: ${{ github.sha }} | |
build_java_package: | |
runs-on: ubuntu-latest | |
if: ${{ !(github.event_name != 'release' && github.event_name != 'workflow_dispatch') }} # !env.IS_SIMPLE_TEST と同じ | |
needs: [config, build_and_deploy] | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Set up Rust | |
uses: ./.github/actions/rust-toolchain-from-file | |
- name: Set up Java | |
uses: actions/setup-java@v4 | |
with: | |
java-version: "17" | |
distribution: "adopt" | |
- uses: nttld/setup-ndk@v1 | |
id: setup-ndk | |
with: | |
ndk-version: r25b | |
- name: Install cargo-binstall | |
uses: taiki-e/install-action@cargo-binstall | |
- name: Install cargo-edit | |
run: cargo binstall cargo-edit@^0.11 --no-confirm | |
- name: set cargo version | |
run: | |
cargo set-version "$VERSION" -p voicevox_core_java_api | |
- name: "Download artifact (android-arm64)" | |
uses: actions/download-artifact@v4 | |
with: | |
name: voicevox_core_java_api-android-arm64 | |
path: artifact/android-arm64 | |
- name: "Download artifact (android-x86_64)" | |
uses: actions/download-artifact@v4 | |
with: | |
name: voicevox_core_java_api-android-x86_64 | |
path: artifact/android-x86_64 | |
- name: Print tree | |
run: tree artifact | |
- name: Build voicevoxcore-android | |
run: | | |
rm -rf crates/voicevox_core_java_api/lib/src/main/resources/dll | |
cat <<EOF | while read -r line; do | |
android-arm64|arm64-v8a | |
android-x86_64|x86_64 | |
EOF | |
IFS='|' read -r artifact_name target <<< "$line" | |
mkdir "crates/voicevox_core_java_api/lib/src/main/resources/jniLibs/${target}/" | |
cp -v "artifact/$artifact_name"/* "crates/voicevox_core_java_api/lib/src/main/resources/jniLibs/${target}/" | |
done | |
cp ${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so crates/voicevox_core_java_api/lib/src/main/resources/jniLibs/arm64-v8a/ | |
cp ${{ steps.setup-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so crates/voicevox_core_java_api/lib/src/main/resources/jniLibs/x86_64/ | |
cd crates/voicevox_core_java_api | |
OS=android DEVICE=cpu gradle publishToMavenLocal | |
- name: Package | |
run: | | |
cd ~/.m2/repository | |
rm -rf dev || true | |
zip -r /tmp/java_packages.zip . | |
- name: Upload to Release | |
if: fromJson(needs.config.outputs.deploy) | |
uses: softprops/action-gh-release@v2 | |
with: | |
prerelease: true | |
tag_name: ${{ env.VERSION }} | |
files: |- | |
/tmp/java_packages.zip | |
target_commitish: ${{ github.sha }} | |
download_test: | |
needs: [config, build_and_deploy] | |
if: fromJson(needs.config.outputs.deploy) | |
uses: ./.github/workflows/download_test.yml | |
with: | |
version: ${{ inputs.version }} |