fix: implement conditional hardware rendering #29
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: | |
| branches: [ "main" ] | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| inputs: | |
| tag_name: | |
| description: 'Tag name (e.g. v1.0.8)' | |
| required: false | |
| default: '' | |
| permissions: | |
| contents: write | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| jobs: | |
| release: | |
| name: Build & Publish Release | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Compute and Increment Version | |
| id: version_step | |
| run: | | |
| RUN_NUM="${{ github.run_number }}" | |
| CALC_CODE=$((100 + RUN_NUM)) | |
| if [[ "${{ github.ref }}" == refs/tags/v* ]]; then | |
| TAG="${{ github.ref_name }}" | |
| VER="${TAG#v}" | |
| elif [ -n "${{ inputs.tag_name }}" ]; then | |
| TAG="${{ inputs.tag_name }}" | |
| VER="${TAG#v}" | |
| else | |
| VER="1.0.${CALC_CODE}" | |
| TAG="v${VER}" | |
| fi | |
| echo "APP_VERSION_CODE=${CALC_CODE}" >> $GITHUB_ENV | |
| echo "APP_VERSION_NAME=${VER}" >> $GITHUB_ENV | |
| echo "tag=${TAG}" >> $GITHUB_OUTPUT | |
| echo "version=${VER}" >> $GITHUB_OUTPUT | |
| echo "version_code=${CALC_CODE}" >> $GITHUB_OUTPUT | |
| echo "Target Tag: ${TAG} (Version Name: ${VER}, Version Code: ${CALC_CODE})" | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: '21' | |
| distribution: 'microsoft' | |
| - name: Setup Gradle Build Cache | |
| uses: gradle/actions/setup-gradle@v4 | |
| with: | |
| cache-read-only: false | |
| - name: Setup Android Release Keystore | |
| run: | | |
| if [ -n "${{ secrets.RELEASE_KEYSTORE_BASE64 }}" ]; then | |
| echo "Decoding permanent release.keystore from GitHub Secret..." | |
| echo "${{ secrets.RELEASE_KEYSTORE_BASE64 }}" | base64 -d > release.keystore | |
| elif [ -f release.keystore ]; then | |
| echo "Using existing release.keystore from workspace..." | |
| else | |
| echo "Decoding permanent deterministic release.keystore to guarantee seamless in-place updates..." | |
| echo "MIILPgIBAzCCCugGCSqGSIb3DQEHAaCCCtkEggrVMIIK0TCCBcgGCSqGSIb3DQEHAaCCBbkEggW1MIIFsTCCBa0GCyqGSIb3DQEMCgECoIIFQDCCBTwwZgYJKoZIhvcNAQUNMFkwOAYJKoZIhvcNAQUMMCsEFP7wxtLaBT0YPiohLqiOIStQoTdAAgInEAIBIDAMBggqhkiG9w0CCQUAMB0GCWCGSAFlAwQBKgQQV6D92NTqnTyley8MXOMvjwSCBNBNi60fxvpKhpW/MLw5soKZ6Z8YqOkRZJbEFFUPjcOAJ4U1nXejvG8A3W9owuEO+axlAIb6j+soFqRJAw3p8Zq+VIBoyChVNLyZMFoOxZnLWM6lDBLbkxq6tWxONm51mlO7JV7OFExN4ZGItTsT2SenMz+0uCl5JF34B6CJOQDMWseu/HE1AvyIYnjxvN9Dh0NsoRHrDzzaX5kfGhUINJfo5n2flFEgxK4s3CjhUkTSJDw2A1EMH0ZfHANuZuolnp6OwbJqXilkRHVMYYhScDycedOPr2MexM8yUgDeEUneyTSR6MFKWocoLWGe0MkdDqTXcLDEgmnTUkqt9sF6ob69e3b//d2PfLxY2zSXBS68EajhVInps6XQJUXJXYIxMdejm+eOcx59IJ7NHAExI98peqizSIPps3BnweVgu+JAqJCkR26OnO26m4oASqlJjDVPnh6yTTbwyfkK4Qvtw1mLIHkqQIVwJEshqFwZZ3w4pRKVOsenmqFJkZalgSprN/eSDpwbMEpJOiO9jPuantG1xw8l9copmw020ZkSPYcC4xpFDjOKRyCa7VBQZR2dOAo3w2p9pwk2z/txQKCiP1OkEYW7h9TUZmRA4h/6IhYlJHZyD/gOOOz754nYAE6MqrCAMiCftuGjmtSkFGLxhAlVWHURyG4LsG3nVfP+1n2jgn8dtPjRzBKKl+W+3Vmo1ma9vPhXZqD0jIpC4myzM7eqT1rsmRru5K4qIxBvUMD4zZnNkcKd4Rku4BU6hpDXqi5qTc/22VpG2llW79pDKC2jZCS9ZZ6TBeE4x/Hn9imeCESL6ptLjoSxp9ebcEQifhaqbxyAi+Yq69993eqq0J5qIV7bEL6LxSCLUW1UHHp6YjpjbN8VAbbkp71ZWwRMGxaqhdhqQZ9a0KdIcHecJH8n6fFKxZ3Y5DqSYGT+V+7HWc8xOyQySxkxrNlPmfVXstMUtpzl05O6z/3b1CyJqF2OLWfI9Bxx13Xr3Uu7vLkKIBtQ8pYZ3kbajNeiePoKBA0HoAOoJLD8WNL+8sRZG/egiadToxwS4ShRN5EvYewyMRlHIFCRo9Pih/a0ReauYAFezBUFEqMBKYUPoDPifv2XAb3gNkO6dtdczRIdk9OPGrvUSRnr5qBmpvESNO+k+P/A7TxU+5fGSxJForcFGFJm8VAkixg1qHkRNl0F8MavsDKGSms1FnDWAQr69YTTWmP0KHbEaO/AgItc0MvdHNTg582CfKRW+nhc6wOTA0Flyh5vSewhsbzrOkn4l1mzEq9io0fZZlBWiDWzFV1huYBwaJt9ReMs2u/7pPznEMQjlluGxkY1Fr+FsQaYxl23DX6ywfvHsoOYa28/w8OLhn1rHRC9rJ6FCOobMYsrOmZljtpLP7cnVxwOQaUpiQmnY2ipEsbyxNUw+BMmIWP9bUmpCAC0mNPPJNYj7PkT6X1B89IJznKEh0FyOCaG+k1e4COcrskYWHB68Xn7L0WGRkNYKk8T0hQ+lK38CsdamY6VqItSSDH0VTxGjsDREsiaZWGxHba/SMc1gQvohhNShCVl6o4P4Dd3BK/J7aBJgQyHZxMRoKmUccRVqsI/gqZ89EN76OSrWkO39RN1PxkkcdhnmzSd0TSdEuoJdXVcyRHcRjFaMDUGCSqGSIb3DQEJFDEoHiYAZgBlAGEAdABoAGUAcgBfAHIAZQBsAGUAYQBzAGUAXwBrAGUAeTAhBgkqhkiG9w0BCRUxFAQSVGltZSAxNzg4Nzc4MzY1OTkwMIIFAQYJKoZIhvcNAQcGoIIE8jCCBO4CAQAwggTnBgkqhkiG9w0BBwEwZgYJKoZIhvcNAQUNMFkwOAYJKoZIhvcNAQUMMCsEFPbe7cWWwes/u+Un2kcfILVpo7llAgInEAIBIDAMBggqhkiG9w0CCQUAMB0GCWCGSAFlAwQBKgQQwirPCnt5+yD9ta2G/5/W6oCCBHCuc+i1fLotScx1mK+zQmTLT+20uaoWCygypOCF5VNuVnVQpe/quOAYN7npT8eTRgZBM/2tBX9h3RP32DBfnE2rkuc9xki/FyGej9NzMlpKZnX9LBnRYAsrxoLLUbRVux9/KbT3cfipCjtxMpqyjXO/YdHlDpXwJbvVLL/lFuLANeJw0IbCpODkBzXtnducE5+o2TeBdbakGNuOiMT5nI/yZlyBieAjVCI74/BrtfnZqeJEHtDFuDzXkcm9h9poKt93yimD151mSKR+MYs3szNyawNHQzEmGgdyXLpjaeajdiAIP2lMjNn494rTC9PyRvB1BG7At+i+JY5LlKUb/M+MRKudIauvdU4Lg+sEhjGhDipyg2avRLXzJAQ+pOuaO9qdeFzWrME9ESR6fZMAOJ7ifsy50OU25flpY+qwvI69hTlzFYy1R4ZW/b7YSRDYUFQw5NeCm+/4cWK5eqXYqodUKBkbjXqqbRA7+vVybNGYMPX7Z9cL5fSy9crG4ycEa9X6Wgs9Fr0/WDBS8va13c/kdl5FuYYZfV768cF7iNKF2dY9G348clfRJnQ6Zs8EAuGkHXiWQ02lb0wEB9D1LeC8pWXwTaWy1yzdH42B7LErwRCz5Nkq0Hw9CNZRlWWvj8fwN99GZKr/IIm5ECl9s9D3DoNBo/0UIpOCoAxk6qIT4SQvYs6mvgWF6J9Q6LMPkBnIQ7fXYlUwDAeFscVXI8QHq9kYUF7RND1GsWH4EMvstbvJ380TZ+dqmLelBUaZbEFNcIVDmD+kVBUYhEigIzw/unJ+rXfmlNOdWKSqxpAeDk6HJS9UFRjvihqP0tGizO6OewRJTf4hgT5U2sycP/zYtPRov+YDxpVfEBgCdQvxmLQBBKEIVwPeORGXtNYsSYsJuWqLeuAuYrCIbBMSMhpcky4cBkfUpT3OCDhYrsfP+R3IUiJhGGSRGj0bzI2JanJfnodpFXHYZWoJnMqUcwCQnTaAu1q/DR7MDGsF1At7fKsjmcz4qdZAdzUWF6k5+dZXLUFNVb7hCGQ3O11quqGtOBreFOpUGEiPlAtt0LOD0xSuV0EwmadLF0soVhxpZRQkgVgVtNbHI/Pn6IUbBnNWQrvtsjPwxD8ubgr8EoEXcps+QLC4R4coCAwd2KQ3d32LE3c0hvTrt/dqRUykfgq/360C92WfIGQ3vRwKVN6d8ioQiw209sKiIxqE1LNDqiJUK5/RU/mdtwa3B10AcmXI+F0qSqRO7yCYucaF891hTjrELDSKyHVm8COagCqC74wr2WccgEYFnQv5SON+udDf8g8qmEtKgjZ0U4/bLsBxXVeL7VoEDs6SG23QygObXcwx84cdxnpd1Dum/GBsmfzUOfo58avC430dAplDNugMFjfsMw7bDGBzdy0vAKP8IbxXEi0jDXt6OaNERz3rE/3Q7gwahQCTWHl4B3KM5YCzdG8iw9jl0glJ2Q9/JC4mgJljrQ3T47Z3m/8z1HpX/nF+hjv11WURCxo+aEQfl27+NDBNMDEwDQYJYIZIAWUDBAIBBQAEIBQkUCXAP5jEiIBLAgdPPuG17j38r5g0kZDNjtJFLEwfBBS4C/4sw2crxgbGOR1H894hhQsWDwICJxA=" | base64 -d > release.keystore | |
| fi | |
| if [ ! -f debug.keystore ]; then | |
| cp release.keystore debug.keystore || true | |
| fi | |
| - name: Grant execute permission for gradlew | |
| run: chmod +x gradlew | |
| - name: Build Release APK | |
| run: ./gradlew assembleRelease --build-cache --parallel -Dorg.gradle.jvmargs="-Xmx4096m -XX:+UseParallelGC" --stacktrace | |
| - name: Prepare Release Assets | |
| id: prepare_asset | |
| run: | | |
| TAG="${{ steps.version_step.outputs.tag }}" | |
| VER="${{ steps.version_step.outputs.version }}" | |
| mkdir -p release-assets | |
| APK_NAME="Feather-Browser-${TAG}.apk" | |
| FOUND_APK=$(find app/build/outputs/apk/release -name "*.apk" 2>/dev/null | head -n 1) | |
| if [ -z "$FOUND_APK" ]; then | |
| FOUND_APK=$(find . -name "*release*.apk" 2>/dev/null | head -n 1) | |
| fi | |
| if [ -n "$FOUND_APK" ] && [ -f "$FOUND_APK" ]; then | |
| cp "$FOUND_APK" "release-assets/${APK_NAME}" | |
| elif [ -f app/build/outputs/apk/release/app-release.apk ]; then | |
| cp app/build/outputs/apk/release/app-release.apk "release-assets/${APK_NAME}" | |
| else | |
| echo "Error: Release APK not found!" | |
| find . -name "*.apk" | |
| exit 1 | |
| fi | |
| cd release-assets | |
| sha256sum "${APK_NAME}" > "${APK_NAME}.sha256" | |
| echo "apk_name=${APK_NAME}" >> $GITHUB_OUTPUT | |
| - name: Upload APK as Workflow Artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ steps.prepare_asset.outputs.apk_name }} | |
| path: release-assets/* | |
| retention-days: 90 | |
| - name: Publish GitHub Release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| TAG="${{ steps.version_step.outputs.tag }}" | |
| VER="${{ steps.version_step.outputs.version }}" | |
| echo "Publishing release for ${TAG}..." | |
| # Delete existing release & tag on GitHub if re-running or updating | |
| gh release delete "${TAG}" --yes --cleanup-tag 2>/dev/null || true | |
| # Create release and upload all assets with GitHub CLI | |
| gh release create "${TAG}" release-assets/* \ | |
| --title "Feather Browser ${TAG}" \ | |
| --generate-notes \ | |
| --latest \ | |
| --target "${{ github.sha }}" | |