New Crowdin updates #2492
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: FieldWorks Lite | |
| on: | |
| workflow_dispatch: | |
| push: | |
| paths: | |
| - 'backend/FwLite/**' | |
| - 'backend/harmony/**' | |
| - 'frontend/viewer/**' | |
| - '.github/workflows/fw-lite.yaml' | |
| - 'FwLiteOnly.slnf' | |
| branches: | |
| - develop | |
| - main | |
| pull_request: | |
| paths: | |
| - 'backend/FwLite/**' | |
| - 'backend/harmony/**' | |
| - 'frontend/viewer/**' | |
| - '.github/workflows/fw-lite.yaml' | |
| - 'FwLiteOnly.slnf' | |
| branches: | |
| - develop | |
| - main | |
| - shadcn-ui-main #just for now ensure PRs to this branch have checks run | |
| env: | |
| VIEWER_BUILD_OUTPUT_DIR: backend/FwLite/FwLiteShared/wwwroot/viewer | |
| jobs: | |
| build-and-test: | |
| name: Build FW Lite and run tests | |
| timeout-minutes: 40 | |
| runs-on: windows-latest | |
| outputs: | |
| version: ${{ steps.setVersion.outputs.VERSION }} | |
| semver-version: ${{ steps.setVersion.outputs.SEMVER_VERSION }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '9.x' | |
| - name: Install Task | |
| uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 #v2 | |
| with: | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set Version | |
| id: setVersion | |
| shell: bash | |
| # set version to date in vYYYY-MM-DD-commitSha format, and semver version to YYYY.MM.DD | |
| run: | | |
| shortSha=$(echo ${{ github.sha }} | cut -c1-8) | |
| echo "VERSION=v$(date --rfc-3339=date)-$shortSha" >> ${GITHUB_OUTPUT} | |
| echo "SEMVER_VERSION=$(date +%Y.%-m.%-d)" >> ${GITHUB_OUTPUT} | |
| - name: Dotnet build | |
| # the android build is quite slow, so we disable it for builds just for testing | |
| run: dotnet build FwLiteOnly.slnf -p:BuildAndroid=false | |
| - name: Check for pending EF model changes | |
| run: task fw-lite:has-pending-model-changes -- --no-build | |
| - name: Dotnet test | |
| run: dotnet test FwLiteOnly.slnf --logger GitHubActions --no-build | |
| frontend: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 | |
| with: | |
| package_json_file: 'frontend/package.json' | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: './frontend/package.json' | |
| cache: 'pnpm' | |
| cache-dependency-path: './frontend/pnpm-lock.yaml' | |
| - name: Install Task | |
| uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 #v2 | |
| with: | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Prepare frontend | |
| working-directory: frontend | |
| run: | | |
| pnpm install | |
| - name: Ensure all i18n strings have been extracted | |
| working-directory: frontend/viewer | |
| shell: bash | |
| run: | | |
| set -e | |
| # GHA sets -o pipefail when shell is bash but we want to turn it off | |
| set +o pipefail | |
| rm -f src/locales/en.po.old | |
| cp src/locales/en.po src/locales/en.po.old | |
| pnpm i18n:extract | |
| DIFFCOUNT=$(diff -u src/locales/en.po{.old,} | grep '+msgid' | wc -l) | |
| if [ $DIFFCOUNT -gt 0 ]; then | |
| # Unextracted strings found, fail the build | |
| echo '***' | |
| echo $DIFFCOUNT unextracted strings found: | |
| echo '***' | |
| diff -u src/locales/en.po{.old,} | grep '+msgid' | cut -c2- | |
| echo '***' | |
| echo Please run pnpm i18n:extract | |
| exit 1 | |
| fi | |
| rm -f src/locales/en.po.old | |
| - name: Set up Playwright dependencies | |
| working-directory: frontend | |
| run: pnpm exec playwright install --with-deps | |
| - name: Run snapshot tests | |
| working-directory: frontend/viewer | |
| run: task playwright-test-standalone | |
| - name: Build viewer | |
| working-directory: frontend/viewer | |
| run: pnpm run build | |
| - name: Upload viewer artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fw-lite-viewer-js | |
| if-no-files-found: error | |
| path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} | |
| frontend-component-unit-tests: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 | |
| with: | |
| package_json_file: 'frontend/package.json' | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: './frontend/package.json' | |
| cache: 'pnpm' | |
| cache-dependency-path: './frontend/pnpm-lock.yaml' | |
| - name: Prepare frontend | |
| working-directory: frontend | |
| run: | | |
| pnpm install | |
| # vitest is configured to use playwright for stories and other browser-based tests | |
| - name: Set up Playwright dependencies | |
| working-directory: frontend/viewer | |
| run: pnpm exec playwright install --with-deps | |
| - name: vitest | |
| working-directory: frontend/viewer | |
| run: pnpm run test --reporter=default --reporter=junit --outputFile.junit=test-results/vitest-results.xml | |
| - name: Publish unit test results | |
| uses: EnricoMi/publish-unit-test-result-action@8885e273a4343cd7b48eaa72428dea0c3067ea98 # v2.14.0 | |
| if: always() | |
| with: | |
| check_name: UI unit Tests | |
| files: ./frontend/viewer/test-results/*.xml | |
| action_fail_on_inconclusive: true | |
| publish-mac: | |
| name: Publish FW Lite app for Mac | |
| needs: [build-and-test, frontend] | |
| timeout-minutes: 30 | |
| runs-on: macos-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: fw-lite-viewer-js | |
| path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} | |
| - uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '9.x' | |
| - name: Dotnet build | |
| working-directory: backend/FwLite/FwLiteWeb | |
| run: dotnet build --configuration Release | |
| - name: Publish OSX | |
| working-directory: backend/FwLite/FwLiteWeb | |
| run: dotnet publish -r osx-x64 --artifacts-path ../artifacts -p:Version=${{ needs.build-and-test.outputs.semver-version }} | |
| - name: Publish OSX ARM | |
| working-directory: backend/FwLite/FwLiteWeb | |
| run: dotnet publish -r osx-arm64 --artifacts-path ../artifacts -p:Version=${{ needs.build-and-test.outputs.semver-version }} | |
| #todo sign the app | |
| - name: Upload local web app artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fw-lite-web-mac | |
| if-no-files-found: error | |
| path: backend/FwLite/artifacts/publish/FwLiteWeb/* | |
| publish-linux: | |
| name: Publish FW Lite app for Linux | |
| needs: [ build-and-test, frontend ] | |
| timeout-minutes: 30 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: fw-lite-viewer-js | |
| path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} | |
| - uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '9.x' | |
| - name: Publish Linux | |
| working-directory: backend/FwLite/FwLiteWeb | |
| run: | | |
| dotnet publish -r linux-x64 --artifacts-path ../artifacts -p:PublishSingleFile=true -p:Version=${{ needs.build-and-test.outputs.semver-version }} | |
| dotnet publish -r linux-arm64 --artifacts-path ../artifacts -p:PublishSingleFile=true -p:Version=${{ needs.build-and-test.outputs.semver-version }} | |
| - name: Test Linux executable | |
| working-directory: backend/FwLite/artifacts/publish/FwLiteWeb/release_linux-x64 | |
| run: | | |
| set +e | |
| chmod +x ./FwLiteWeb | |
| output=$(timeout 10s ./FwLiteWeb 2>&1) | |
| exit_code=$? | |
| if [ $exit_code -eq 124 ] || [ $exit_code -eq 0 ]; then | |
| echo "✅ Linux executable ran without crashing for 10s" | |
| else | |
| echo "❌ Linux executable exited with code $exit_code" | |
| echo "$output" | |
| exit 1 | |
| fi | |
| - name: Upload FWLite Linux artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fw-lite-web-linux | |
| if-no-files-found: error | |
| path: backend/FwLite/artifacts/publish/FwLiteWeb/* | |
| publish-android: | |
| name: Publish FW Lite app for Android | |
| needs: [ build-and-test, frontend ] | |
| timeout-minutes: 30 | |
| runs-on: macos-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: fw-lite-viewer-js | |
| path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} | |
| - uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '9.x' | |
| - name: Setup Maui | |
| run: dotnet workload install maui | |
| - name: Decode Android Keystore | |
| id: decodeKeystore | |
| env: | |
| KEYSTORE_BASE64: ${{ secrets.FW_LITE_KEYSTORE_BASE64 }} | |
| run: | | |
| echo "KEYSTORE_PATH=${RUNNER_TEMP}/keystore.jks" >> ${GITHUB_OUTPUT} | |
| base64 -d <<< "$KEYSTORE_BASE64" > ${RUNNER_TEMP}/keystore.jks | |
| - name: Publish Android | |
| working-directory: backend/FwLite/FwLiteMaui | |
| env: | |
| KEYSTORE_PATH: ${{ steps.decodeKeystore.outputs.KEYSTORE_PATH }} | |
| KEYSTORE_PASS: ${{ secrets.FW_LITE_KEYSTORE_PASS }} | |
| KEYSTORE_ALIAS: ${{ vars.FW_LITE_KEYSTORE_UPLOAD_KEY_ALIAS }} | |
| run: | | |
| dotnet publish -f net9.0-android -p:BuildApple=false --artifacts-path ../artifacts \ | |
| -p:ApplicationDisplayVersion=${{ needs.build-and-test.outputs.semver-version }} \ | |
| -p:ApplicationVersion=${{ github.run_number }} \ | |
| -p:InformationalVersion=${{ needs.build-and-test.outputs.version }} \ | |
| -p:AndroidKeyStore=true \ | |
| -p:AndroidSigningKeyStore=${KEYSTORE_PATH} \ | |
| -p:AndroidSigningKeyPass=env:KEYSTORE_PASS \ | |
| -p:AndroidSigningStorePass=env:KEYSTORE_PASS \ | |
| -p:AndroidSigningKeyAlias=${KEYSTORE_ALIAS} | |
| rm ${KEYSTORE_PATH} | |
| - name: Upload FWLite App artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fw-lite-android | |
| if-no-files-found: error | |
| # path looks like this: backend/FwLite/artifacts/publish/FwLiteMaui/release_net9.0-android/org.sil.fwlitemaui-signed.apk | |
| path: backend/FwLite/artifacts/publish/FwLiteMaui/release_net9.0-android/* | |
| publish-win: | |
| name: Publish FW Lite app for Windows | |
| needs: [ build-and-test, frontend ] | |
| timeout-minutes: 30 | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: fw-lite-viewer-js | |
| path: ${{ env.VIEWER_BUILD_OUTPUT_DIR }} | |
| - uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '9.x' | |
| - name: Setup Maui | |
| run: dotnet workload install maui | |
| - name: Publish Windows MAUI portable app | |
| working-directory: backend/FwLite/FwLiteMaui | |
| run: | | |
| dotnet publish -f net9.0-windows10.0.19041.0 -p:BuildAndroid=false --artifacts-path ../artifacts -p:WindowsPackageType=None -p:ApplicationDisplayVersion=${{ needs.build-and-test.outputs.semver-version }} -p:InformationalVersion=${{ needs.build-and-test.outputs.version }} | |
| mkdir -p ../artifacts/sign/portable | |
| cp -r ../artifacts/publish/FwLiteMaui/* ../artifacts/sign/portable/ | |
| - name: Publish Windows MAUI msix app | |
| working-directory: backend/FwLite/FwLiteMaui | |
| run: | | |
| dotnet publish -f net9.0-windows10.0.19041.0 -p:BuildAndroid=false --artifacts-path ../artifacts -p:ApplicationDisplayVersion=${{ needs.build-and-test.outputs.semver-version }} -p:InformationalVersion=${{ needs.build-and-test.outputs.version }} | |
| mkdir -p ../artifacts/msix | |
| cp ../artifacts/bin/FwLiteMaui/*/AppPackages/*/*.msix ../artifacts/msix/ | |
| - name: Bundle MSIX | |
| working-directory: backend/FwLite/artifacts/msix | |
| shell: pwsh | |
| run: | | |
| $SdkVersion = '10.0.26100.0' | |
| $Architecture = 'x86' | |
| $sdkToolsPath = Join-Path -Path 'C:\Program Files (x86)\Windows Kits\10\bin' -ChildPath $SdkVersion -AdditionalChildPath $Architecture | |
| $env:Path += ";$sdkToolsPath" | |
| MakeAppx.exe bundle /v /bv ${{ needs.build-and-test.outputs.semver-version }}.1 /d . /p ../sign/FwLiteMaui.msixbundle | |
| - name: Sign with Trusted Signing | |
| if: ${{ github.ref_name == 'develop' || github.ref_name == 'main' }} | |
| uses: sillsdev/codesign/trusted-signing-action@v3 | |
| with: | |
| credentials: ${{ secrets.TRUSTED_SIGNING_CREDENTIALS }} | |
| files-folder: ${{ github.workspace }}/backend/FwLite/artifacts/sign | |
| files-folder-filter: msixbundle,exe | |
| files-folder-recurse: true | |
| files-folder-depth: 4 | |
| description: 'Release for version ${{ needs.build-and-test.outputs.version }} from branch ${{ github.ref_name || github.head_ref }}' | |
| description-url: 'https://github.com/sillsdev/languageforge-lexbox' | |
| - name: Upload FWLite Portable | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fw-lite-portable | |
| if-no-files-found: error | |
| path: backend/FwLite/artifacts/sign/portable/* | |
| - name: Upload FWLite MSIX | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fw-lite-msix | |
| if-no-files-found: error | |
| path: backend/FwLite/artifacts/sign/*.msixbundle | |
| create-release: | |
| if: ${{ github.ref_name == 'main' }} | |
| environment: | |
| name: production | |
| url: https://lexbox.org/fw-lite | |
| name: Create Release | |
| needs: [ build-and-test, publish-win, publish-linux, publish-mac, publish-android] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: fw-lite-msix | |
| path: fw-lite-msix | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: fw-lite-portable | |
| path: fw-lite-portable | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: fw-lite-web-linux | |
| path: fw-lite-web-linux | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: fw-lite-android | |
| path: fw-lite-android | |
| - name: Zip artifacts | |
| run: | | |
| zip -r fw-lite-portable.zip fw-lite-portable | |
| chmod +x fw-lite-web-linux/*/FwLiteWeb fw-lite-web-linux/*/*.sh | |
| zip -r fw-lite-web-linux.zip fw-lite-web-linux | |
| - name: Rename Installer | |
| run: | | |
| mv fw-lite-msix/FwLiteMaui.msixbundle fw-lite-msix/FieldWorksLiteInstaller.msixbundle | |
| - name: Create Release | |
| uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda #v2.2.1 | |
| with: | |
| tag_name: ${{ needs.build-and-test.outputs.version }} | |
| target_commitish: ${{ github.sha }} | |
| generate_release_notes: true | |
| files: | | |
| fw-lite-msix/* | |
| fw-lite-portable.zip | |
| fw-lite-web-linux.zip | |
| fw-lite-android/*.apk | |
| fw-lite-android/*.aab | |
| - name: Invalidate Lexbox Release endpoint | |
| continue-on-error: true | |
| run: | | |
| sleep 10 | |
| curl -X POST https://lexbox.org/api/fwlite-release/new-release | |