Repository navigation
2.18.4: udp:// receive thread at the audio priority (#253) #934
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: Build | |
| on: | |
| push: | |
| pull_request: | |
| workflow_dispatch: | |
| inputs: | |
| commit_hash: | |
| description: 'Specific commit SHA to build (leave empty for latest branch commit)' | |
| required: false | |
| type: string | |
| # One run per branch (and event). On working branches a newer push cancels the older run; | |
| # on basic / v2 it waits instead (only the newest waits), so "latest" still ends with the | |
| # build of the newest commit (#90) and a publish is never cut off halfway. A manual run of the | |
| # branch head shares that group (so each branch has one publish at a time and the shared | |
| # release-latest group below never holds more than one waiting job); a manual run of an older | |
| # commit (commit_hash) has a group of its own and does not publish. | |
| concurrency: | |
| group: ${{ github.event_name == 'workflow_dispatch' && inputs.commit_hash != '' && format('manual-{0}', github.run_id) || format('build-{0}-{1}', github.event_name == 'pull_request' && 'pull_request' || 'push', github.ref) }} | |
| cancel-in-progress: ${{ !(github.event_name == 'workflow_dispatch' && inputs.commit_hash != '') && github.ref != 'refs/heads/v2' && github.ref != 'refs/heads/basic' }} | |
| # Read-only by default; only the publish job writes the release | |
| permissions: | |
| contents: read | |
| jobs: | |
| # The version check of pull requests is .github/workflows/version.yml (#244). | |
| # Unit tests and lint; also runs for pull requests from forks (no secrets needed) | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Switch to specified commit (keep latest workflow files) | |
| if: inputs.commit_hash != '' | |
| run: | | |
| git fetch --unshallow | |
| git checkout ${{ inputs.commit_hash }} | |
| git checkout ${{ github.ref_name }} -- .github/ | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: 17 | |
| cache: gradle | |
| - name: Unit tests and lint | |
| working-directory: android | |
| run: | | |
| ./gradlew testDebugUnitTest | |
| # Commits from before the lint baseline would fail on known findings | |
| if [ -f app/lint-baseline.xml ]; then | |
| ./gradlew lintDebug | |
| else | |
| echo "No lint baseline in this commit, lint skipped" | |
| fi | |
| - name: Upload reports | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: test-and-lint-reports | |
| path: | | |
| android/app/build/reports/ | |
| android/app/build/test-results/ | |
| # Signed release build; needs secrets, so it does not run for pull requests | |
| build: | |
| needs: test | |
| if: github.event_name != 'pull_request' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| mapping: ${{ steps.apk.outputs.mapping }} # 1 when the build has an R8 mapping | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Switch to specified commit (keep latest workflow files) | |
| if: inputs.commit_hash != '' | |
| run: | | |
| git fetch --unshallow | |
| git checkout ${{ inputs.commit_hash }} | |
| git checkout ${{ github.ref_name }} -- .github/ | |
| - name: Set artifact name | |
| id: vars | |
| run: | | |
| case "${{ github.ref_name }}" in | |
| basic) echo "name=decoder" ;; | |
| v2) echo "name=decoder-v2" ;; | |
| *) echo "name=decoder-$(echo '${{ github.ref_name }}' | tr '/' '-')" ;; | |
| esac >> $GITHUB_OUTPUT | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: 17 | |
| cache: gradle | |
| - name: Build | |
| id: apk | |
| working-directory: android | |
| env: | |
| KEYSTORE_PASS: ${{ secrets.KEYSTORE_PASS }} | |
| KEY_ALIAS: ${{ secrets.KEY_ALIAS }} | |
| KEY_PASS: ${{ secrets.KEY_PASS }} | |
| run: | | |
| echo "${{ secrets.KEY }}" | base64 -d > key.jks | |
| # APK only while in development; the .aab (bundleRelease) is for store uploads | |
| ./gradlew assembleRelease | |
| mv app/build/outputs/apk/release/app-release.apk ../${{ steps.vars.outputs.name }}.apk | |
| # R8 mapping of this APK, to retrace obfuscated stack traces (#181). A build without | |
| # minify has none: warn instead of failing | |
| MAPPING=app/build/outputs/mapping/release/mapping.txt | |
| if [ -f "$MAPPING" ]; then | |
| cp "$MAPPING" ../${{ steps.vars.outputs.name }}-mapping.txt | |
| echo "mapping=1" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "::warning::No R8 mapping.txt at $MAPPING" | |
| fi | |
| # Every build keeps its R8 mapping as a workflow artifact (#181) | |
| - name: Upload mapping | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ steps.vars.outputs.name }}-mapping | |
| path: ${{ steps.vars.outputs.name }}-mapping.txt | |
| if-no-files-found: warn | |
| # Every build is a workflow artifact; on basic / v2 the publish job takes it from here | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ steps.vars.outputs.name }} | |
| path: ${{ steps.vars.outputs.name }}.apk | |
| # The one release, "latest" (#194, #229): updated in place by v2 and basic, each with its | |
| # own files; v2 moves the tag to its commit and sets the title "Decoder <version>". | |
| # A new version (not every build) goes to Telegram. The | |
| # concurrency group is shared with basic's workflow: one publish at a time. | |
| publish: | |
| needs: build | |
| # basic publishes from its own workflow (same script, same concurrency group); a manual | |
| # run of an older commit (commit_hash) builds but does not publish | |
| if: github.ref_name == 'v2' && (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.commit_hash == '')) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write # update the release and move its tag | |
| concurrency: | |
| group: release-latest | |
| cancel-in-progress: false | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Download the build | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: decoder-v2 | |
| path: dist | |
| # only when the build has one (a build without minify has none, #181); then it must come | |
| - name: Download the mapping | |
| if: needs.build.outputs.mapping == '1' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: decoder-v2-mapping | |
| path: dist | |
| - name: Publish | |
| id: publish | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| VER=$(sed -n 's/^[[:space:]]*versionName[[:space:]]*"\([^"]*\)"[[:space:]]*$/\1/p' android/app/build.gradle) | |
| [ -n "$VER" ] || { echo "::error::no versionName in android/app/build.gradle"; exit 1; } | |
| echo "VER=$VER" >> "$GITHUB_ENV" | |
| files=(dist/decoder-v2.apk) | |
| [ -f dist/decoder-v2-mapping.txt ] && files+=(dist/decoder-v2-mapping.txt) | |
| .github/publish-latest.sh v2 "$VER" "${files[@]}" | |
| # Organization secrets; a failed upload is a warning, not a failed release | |
| - name: Telegram | |
| if: steps.publish.outputs.new == 'true' | |
| env: | |
| TG_TOKEN: ${{ secrets.TELEGRAM_TOKEN_BOT_OPENIPC }} | |
| TG_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL_OPENIPC_DEV }} | |
| run: | | |
| if [ -z "$TG_TOKEN" ] || [ -z "$TG_CHANNEL" ]; then | |
| echo "::warning::Telegram secrets are not available, version not announced"; exit 0 | |
| fi | |
| CAPTION=$(printf 'Decoder %s\nCommit: %s\nBranch: %s\nTime: %s\n\n%s' "$VER" "${GITHUB_SHA::7}" \ | |
| "${GITHUB_REF_NAME}" "$(date -u '+%Y-%m-%d %H:%M:%S UTC')" \ | |
| "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/latest") | |
| HTTP=$(curl -sS -o tg.json -w '%{http_code}' "https://api.telegram.org/bot${TG_TOKEN}/sendDocument" \ | |
| -F chat_id="$TG_CHANNEL" -F caption="$CAPTION" -F document=@dist/decoder-v2.apk) || HTTP=000 | |
| echo "Telegram response: $HTTP" | |
| [ "$HTTP" = 200 ] || echo "::warning::Telegram upload failed (HTTP $HTTP)" |