Skip to content

CI · docs: add GitHub and F-Droid download buttons #111

CI · docs: add GitHub and F-Droid download buttons

CI · docs: add GitHub and F-Droid download buttons #111

Workflow file for this run

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)$/'