Repository navigation
CI · docs: add GitHub and F-Droid download buttons #111
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: CI | |
| run-name: CI · ${{ github.event.pull_request.title || github.ref_name }} | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_dry_run_version: | |
| description: "Optional release version X.Y.Z for a read-only check with live changelog generation" | |
| required: false | |
| type: string | |
| pull_request: | |
| push: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| release-dry-run: | |
| name: Release dry run | |
| if: github.event_name == 'workflow_dispatch' && inputs.release_dry_run_version != '' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Check release configuration and generate changelogs | |
| env: | |
| GH_TOKEN: ${{ secrets.RELEASE_BOT_TOKEN }} | |
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
| OPENAI_RELEASE_MODEL: ${{ vars.OPENAI_RELEASE_MODEL || secrets.OPENAI_RELEASE_MODEL }} | |
| RELEASE_VERSION: ${{ inputs.release_dry_run_version }} | |
| run: | | |
| test -n "$GH_TOKEN" && test -n "$OPENAI_API_KEY" && test -n "$OPENAI_RELEASE_MODEL" | |
| gh auth setup-git | |
| python3 scripts/release_automation.py prepare --version "$RELEASE_VERSION" --dry-run | |
| release-identity: | |
| name: Release CI identity | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 'Comparison base: ${{ github.event.pull_request.base.sha }}' | |
| run: 'true' | |
| - name: 'Pull request: ${{ github.event.pull_request.number }}' | |
| run: 'true' | |
| android: | |
| name: Android tests and checks | |
| if: github.event_name != 'workflow_dispatch' || inputs.release_dry_run_version == '' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-java@v5 | |
| with: | |
| distribution: temurin | |
| java-version: "21" | |
| - uses: gradle/actions/setup-gradle@v4 | |
| - uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: "3.4.10" | |
| bundler-cache: true | |
| - name: Install Android SDK components | |
| run: | | |
| sdkmanager="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" | |
| if [[ ! -x "$sdkmanager" ]]; then | |
| echo "Android SDK manager is unavailable: $sdkmanager" >&2 | |
| exit 1 | |
| fi | |
| "$sdkmanager" "platforms;android-36" "build-tools;36.0.0" | |
| - run: bundle exec fastlane android checks | |
| - name: Check branding vector conversion | |
| env: | |
| MESSAGE487_TEST_ANDROID_VECTORS: "1" | |
| run: python3 -m unittest discover -s scripts/tests -p test_generate_branding.py | |
| - name: Publish test and lint reports | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: android-test-reports | |
| path: | | |
| app/build/reports/tests/ | |
| app/build/test-results/ | |
| app/build/reports/lint-results-* | |
| if-no-files-found: warn | |
| retention-days: 14 | |
| - name: Upload Android JUnit reports | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: junit-Android JVM | |
| path: app/build/test-results/testDebugUnitTest/*.xml | |
| retention-days: 14 | |
| - uses: actions/upload-artifact@v7 | |
| id: apk | |
| with: | |
| name: message487-pr-${{ github.event.pull_request.number || github.run_id }}-debug-apk | |
| path: app/build/outputs/apk/debug/app-debug.apk | |
| if-no-files-found: error | |
| retention-days: 14 | |
| - uses: actions/upload-artifact@v7 | |
| id: release_apk | |
| with: | |
| name: message487-pr-${{ github.event.pull_request.number || github.run_id }}-unsigned-release-apk | |
| path: app/build/outputs/apk/release/app-release-unsigned.apk | |
| if-no-files-found: error | |
| retention-days: 14 | |
| - name: Link build artifacts | |
| env: | |
| DEBUG_URL: ${{ steps.apk.outputs.artifact-url }} | |
| RELEASE_URL: ${{ steps.release_apk.outputs.artifact-url }} | |
| run: | | |
| echo "[Download debug APK]($DEBUG_URL)" >> "$GITHUB_STEP_SUMMARY" | |
| echo "[Download unsigned release APK]($RELEASE_URL)" >> "$GITHUB_STEP_SUMMARY" | |
| python: | |
| if: github.event_name != 'workflow_dispatch' || inputs.release_dry_run_version == '' | |
| name: Python tests and style | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: "3.4.10" | |
| bundler-cache: true | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: requirements-dev.txt | |
| - run: python -m pip install -r requirements-dev.txt | |
| - run: bundle exec fastlane android python_checks | |
| - name: Upload Python JUnit reports | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: junit-Python | |
| path: test-results/python/**/*.xml | |
| retention-days: 14 | |
| dev-server: | |
| name: Development server tests | |
| if: github.event_name != 'workflow_dispatch' || inputs.release_dry_run_version == '' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: false | |
| - run: docker compose -f DevServer/compose.yaml up -d --wait --wait-timeout 300 | |
| - uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: "3.4.10" | |
| bundler-cache: true | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - run: python -m pip install -r requirements-dev.txt | |
| - run: bundle exec fastlane android server_tests | |
| - name: Upload n8n JUnit reports | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: junit-n8n | |
| path: test-results/server/*.xml | |
| retention-days: 14 | |
| - name: Server logs | |
| if: failure() | |
| run: docker compose -f DevServer/compose.yaml logs --tail 150 | |
| - name: Stop server | |
| if: always() | |
| run: docker compose -f DevServer/compose.yaml down | |
| emulator26: | |
| name: Android emulator API 26 | |
| if: github.event_name != 'workflow_dispatch' || inputs.release_dry_run_version == '' | |
| uses: ./.github/workflows/android-device.yml | |
| with: | |
| api: 26 | |
| emulator35: | |
| name: Android emulator API 35 | |
| if: github.event_name != 'workflow_dispatch' || inputs.release_dry_run_version == '' | |
| uses: ./.github/workflows/android-device.yml | |
| with: | |
| api: 35 | |
| report-android: | |
| name: Publish Android JVM results | |
| needs: android | |
| if: >- | |
| !cancelled() && needs.android.result != 'skipped' && | |
| (github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository) | |
| permissions: | |
| contents: read | |
| actions: read | |
| checks: write | |
| uses: ./.github/workflows/test-reports.yml | |
| with: | |
| artifact: '/^junit-(Android JVM)$/' | |
| report-python: | |
| name: Publish Python results | |
| needs: python | |
| if: >- | |
| !cancelled() && needs.python.result != 'skipped' && | |
| (github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository) | |
| permissions: | |
| contents: read | |
| actions: read | |
| checks: write | |
| uses: ./.github/workflows/test-reports.yml | |
| with: | |
| artifact: '/^junit-(Python)$/' | |
| report-dev-server: | |
| name: Publish n8n results | |
| needs: dev-server | |
| if: >- | |
| !cancelled() && needs.dev-server.result != 'skipped' && | |
| (github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository) | |
| permissions: | |
| contents: read | |
| actions: read | |
| checks: write | |
| uses: ./.github/workflows/test-reports.yml | |
| with: | |
| artifact: '/^junit-(n8n)$/' | |
| report-emulator26: | |
| name: Publish Android API 26 results | |
| needs: emulator26 | |
| if: >- | |
| !cancelled() && needs.emulator26.result != 'skipped' && | |
| (github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository) | |
| permissions: | |
| contents: read | |
| actions: read | |
| checks: write | |
| uses: ./.github/workflows/test-reports.yml | |
| with: | |
| artifact: '/^junit-(Android API 26)$/' | |
| report-emulator35: | |
| name: Publish Android API 35 results | |
| needs: emulator35 | |
| if: >- | |
| !cancelled() && needs.emulator35.result != 'skipped' && | |
| (github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository) | |
| permissions: | |
| contents: read | |
| actions: read | |
| checks: write | |
| uses: ./.github/workflows/test-reports.yml | |
| with: | |
| artifact: '/^junit-(Android API 35)$/' |