Nightly Build #1989
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: Nightly Build | |
| permissions: | |
| contents: write | |
| id-token: write | |
| attestations: write | |
| on: | |
| schedule: | |
| - cron: '45 * * * *' | |
| workflow_dispatch: | |
| jobs: | |
| check-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_build: ${{ steps.check.outputs.should_build }} | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - name: Check for new commits since last nightly tag | |
| id: check | |
| run: | | |
| if git rev-parse nightly >/dev/null 2>&1; then | |
| DIFF=$(git diff nightly..HEAD) | |
| if [ -z "$DIFF" ]; then | |
| echo "No changes since last nightly build - skipping" | |
| echo "should_build=false" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "should_build=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| else | |
| echo "No previous nightly tag found - building" | |
| echo "should_build=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Java | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '21' | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| channel: stable | |
| cache: true | |
| - name: Install dependencies | |
| run: flutter pub get | |
| - name: Generate Version | |
| id: version | |
| run: | | |
| # Generate version: YY.M.0 format (semantic versioning) | |
| YEAR=$(date +'%y') | |
| MONTH=$(date +'%-m') | |
| VERSION="$YEAR.$MONTH.0" | |
| # Generate build number: YYMMDDHH format | |
| BUILD_NUMBER=$(date +'%y%m%d%H') | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "build_number=$BUILD_NUMBER" >> $GITHUB_OUTPUT | |
| - name: Decode Keystore | |
| env: | |
| KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} | |
| run: | | |
| echo "${KEYSTORE_BASE64}" | base64 -d > android/upload-keystore.jks | |
| chmod 600 android/upload-keystore.jks | |
| echo "Keystore decoded and permissions set" | |
| - name: Create key.properties | |
| env: | |
| KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} | |
| KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} | |
| KEY_ALIAS: ${{ secrets.KEY_ALIAS }} | |
| run: | | |
| # Handle non-ASCII characters properly | |
| cat << EOF > android/key.properties | |
| storePassword=${KEYSTORE_PASSWORD} | |
| keyPassword=${KEY_PASSWORD} | |
| keyAlias=${KEY_ALIAS} | |
| storeFile=../upload-keystore.jks | |
| EOF | |
| chmod 600 android/key.properties | |
| echo "Created keystore properties file with restricted permissions" | |
| - name: Verify Keystore | |
| env: | |
| KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} | |
| run: | | |
| ls -la android/upload-keystore.jks | |
| file android/upload-keystore.jks | |
| echo "=== Keystore contents ===" | |
| # Use heredoc to handle non-ASCII characters properly | |
| keytool -list -v -keystore android/upload-keystore.jks -storepass "${KEYSTORE_PASSWORD}" 2>/dev/null || echo "Failed to list keystore contents" | |
| echo "=== End keystore contents ===" | |
| if ! keytool -list -v -keystore android/upload-keystore.jks -storepass "${KEYSTORE_PASSWORD}" 2>/dev/null; then | |
| echo "ERROR: Keystore verification failed - aborting build" | |
| exit 1 | |
| fi | |
| echo "Keystore verification successful" | |
| - name: Build APKs | |
| run: | | |
| flutter build apk --flavor normal --release --obfuscate --split-debug-info=build/debug-info --build-name="${{ steps.version.outputs.version }}" --build-number="${{ steps.version.outputs.build_number }}" --no-pub --tree-shake-icons --dart-define=flutter.web.canvaskit=false --split-per-abi | |
| mkdir -p build/outputs | |
| # Copy and rename split APKs to maintain original naming convention | |
| for apk in build/app/outputs/flutter-apk/app-*-normal-release.apk; do | |
| arch=$(basename "$apk" | sed -e 's/app-//' -e 's/-normal-release.apk//') | |
| cp "$apk" "build/outputs/Updatium-Nightly-${arch}.apk" | |
| done | |
| - name: Attest Build Provenance | |
| uses: actions/attest@v4.1.1 | |
| with: | |
| subject-path: 'build/app/outputs/flutter-apk/*.apk' | |
| - name: Upload Artifacts | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: Updatium-Nightly-APKs | |
| path: | | |
| build/outputs/Updatium-Nightly-*.apk | |
| - name: Create Release | |
| if: success() && hashFiles('build/outputs/Updatium-Nightly-*.apk') != '' | |
| uses: softprops/action-gh-release@master | |
| with: | |
| tag_name: nightly | |
| name: "Updatium Nightly" | |
| files: | | |
| build/outputs/Updatium-Nightly*.apk | |
| prerelease: true | |
| overwrite: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Cleanup signing files | |
| if: always() | |
| run: | | |
| echo "Starting cleanup of sensitive signing files..." | |
| # Cleanup keystore file | |
| if [ -f "$GITHUB_WORKSPACE/android/upload-keystore.jks" ]; then | |
| rm -f "$GITHUB_WORKSPACE/android/upload-keystore.jks" || echo "WARNING: Failed to delete keystore file" | |
| if [ -f "$GITHUB_WORKSPACE/android/upload-keystore.jks" ]; then | |
| echo "ERROR: Keystore file still exists after cleanup attempt" | |
| else | |
| echo "Successfully deleted keystore file" | |
| fi | |
| else | |
| echo "Keystore file not found, nothing to cleanup" | |
| fi | |
| # Cleanup key.properties file | |
| if [ -f "$GITHUB_WORKSPACE/android/key.properties" ]; then | |
| rm -f "$GITHUB_WORKSPACE/android/key.properties" || echo "WARNING: Failed to delete key.properties file" | |
| if [ -f "$GITHUB_WORKSPACE/android/key.properties" ]; then | |
| echo "ERROR: key.properties file still exists after cleanup attempt" | |
| else | |
| echo "Successfully deleted key.properties file" | |
| fi | |
| else | |
| echo "key.properties file not found, nothing to cleanup" | |
| fi | |
| # Unset environment variables | |
| unset KEYSTORE_PASSWORD || echo "WARNING: Failed to unset KEYSTORE_PASSWORD" | |
| unset KEY_PASSWORD || echo "WARNING: Failed to unset KEY_PASSWORD" | |
| unset KEY_ALIAS || echo "WARNING: Failed to unset KEY_ALIAS" | |
| unset KEYSTORE_PASS || echo "WARNING: Failed to unset KEYSTORE_PASS" | |
| echo "Cleanup completed" |