mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 08:15:02 +00:00
ci: run the fork's pipelines on the self-hosted runners
Squash of ten CI commits from 2026-08-04 (all part of HealthChat release 26.08.0): - ci(release): move releases to the persistent self-hosted runners - ci: grant contents:read so checkout works on this private fork - ci: disable the Label Community PRs job on this fork - ci: run the heavy Gradle jobs on the self-hosted runners - ci: rely on the runner image for the Android SDK - ci: size the Gradle heap for the self-hosted containers - ci: report runner capacity on the self-hosted jobs - ci: record why the Gradle heap is reduced - ci: cap Gradle workers so test JVMs fit the container - ci: skip the codecov upload when no token is configured The danger.yml hunk from the contents:read commit is omitted: upstream replaced Danger with a github-script workflow in v26.09.
This commit is contained in:
@@ -7,18 +7,32 @@ on:
|
||||
push:
|
||||
branches: [ develop ]
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
# Private fork: actions/checkout needs contents:read to clone. Upstream is public,
|
||||
# where an empty token can still read the repo, so an empty permissions block works there and
|
||||
# fails here with `fatal: repository not found`.
|
||||
contents: read
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx4g
|
||||
# Reduced from upstream's -Xmx8g / 4 GB Kotlin daemon for the self-hosted runners.
|
||||
# Each incus container reports 48 GiB and 8 cores, so a single build has ample room —
|
||||
# but the containers are oversubscribed against their host, and two concurrent heavy
|
||||
# Gradle jobs get their daemons SIGKILLed ("the daemon has disappeared", no
|
||||
# OutOfMemoryError, no heap dump). Running the same job alone succeeds. Lower heaps
|
||||
# make two builds likelier to coexist; the real fix is sizing the containers to the
|
||||
# host. See the "Report runner capacity" step.
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=768m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx2g
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace -Dsonar.gradle.skipCompile=true --no-configuration-cache
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build APKs
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
permissions:
|
||||
# A job-level block replaces the workflow-level one, so contents:read has to be
|
||||
# repeated here or checkout fails on this private fork.
|
||||
contents: read
|
||||
# For NejcZdovc/comment-pr
|
||||
pull-requests: write
|
||||
strategy:
|
||||
@@ -31,6 +45,9 @@ jobs:
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
# Only meaningful on GitHub's throwaway VMs. On a persistent self-hosted runner this
|
||||
# would delete dotnet/haskell/docker images from the host on every run.
|
||||
if: runner.environment == 'github-hosted'
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
|
||||
with:
|
||||
# This might remove tools that are actually needed, if set to "true" but frees about 6 GB
|
||||
|
||||
@@ -7,17 +7,28 @@ on:
|
||||
push:
|
||||
branches: [ develop ]
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
# Private fork: actions/checkout needs contents:read to clone. Upstream is public,
|
||||
# where an empty token can still read the repo, so an empty permissions block works there and
|
||||
# fails here with `fatal: repository not found`.
|
||||
contents: read
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx4g
|
||||
# Reduced from upstream's -Xmx8g / 4 GB Kotlin daemon for the self-hosted runners.
|
||||
# Each incus container reports 48 GiB and 8 cores, so a single build has ample room —
|
||||
# but the containers are oversubscribed against their host, and two concurrent heavy
|
||||
# Gradle jobs get their daemons SIGKILLed ("the daemon has disappeared", no
|
||||
# OutOfMemoryError, no heap dump). Running the same job alone succeeds. Lower heaps
|
||||
# make two builds likelier to coexist; the real fix is sizing the containers to the
|
||||
# host. See the "Report runner capacity" step.
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=768m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx2g
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace -Dsonar.gradle.skipCompile=true --no-configuration-cache
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Enterprise APKs
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
# Skip in forks
|
||||
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
|
||||
strategy:
|
||||
@@ -30,6 +41,9 @@ jobs:
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
# Only meaningful on GitHub's throwaway VMs. On a persistent self-hosted runner this
|
||||
# would delete dotnet/haskell/docker images from the host on every run.
|
||||
if: runner.environment == 'github-hosted'
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
|
||||
with:
|
||||
# This might remove tools that are actually needed, if set to "true" but frees about 6 GB
|
||||
|
||||
@@ -46,17 +46,24 @@ concurrency:
|
||||
|
||||
env:
|
||||
# Upstream's workflows hardcode -Xmx8g / Kotlin daemon -Xmx4g, sized for the
|
||||
# 4-core/16GB ubuntu-latest that public repos get. On this container the
|
||||
# daemon keeps getting SIGKILLed mid-build (DaemonDisappearedException, no
|
||||
# OutOfMemoryError, no heap dump), so stay well under upstream's ceiling and
|
||||
# leave room for the Kotlin daemon and the parallel lint workers.
|
||||
# 4-core/16GB ubuntu-latest that public repos get. On the previous incus
|
||||
# container the daemon kept getting SIGKILLed mid-build
|
||||
# (DaemonDisappearedException, no OutOfMemoryError, no heap dump), so these
|
||||
# values stay well under upstream's ceiling and leave room for the Kotlin
|
||||
# daemon and the parallel lint workers. Re-check them against the "Report
|
||||
# runner capacity" output now that jobs land on the persistent org runners,
|
||||
# whose specs may differ.
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=768m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx2g
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace --no-daemon -Dsonar.gradle.skipCompile=true --no-configuration-cache
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Build and upload AAB to Play Store
|
||||
runs-on: novaloop-incus-large
|
||||
# Persistent org runners (github-runner-01, gha-runner-1..3). The previous
|
||||
# novaloop-incus-large label pointed at the GARM ephemeral pool, whose freshly
|
||||
# spawned runners were reaped mid-job — jobs died ~10 minutes in with
|
||||
# "The operation was canceled" and no other diagnostic.
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -176,18 +183,14 @@ jobs:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
|
||||
# The self-hosted runner image has no Android SDK (unlike GitHub-hosted
|
||||
# ubuntu-latest), so install it here.
|
||||
# - platform: follows COMPILE_SDK in plugins/src/main/kotlin/Versions.kt.
|
||||
# Platform packages are minor-versioned, so compileSdk 37 is android-37.0.
|
||||
# - build-tools: nothing sets buildToolsVersion, so AGP picks its own
|
||||
# default (SdkConstants.CURRENT_BUILD_TOOLS_VERSION). Bump it when AGP is
|
||||
# upgraded, not when Versions.kt changes.
|
||||
- name: Set up Android SDK
|
||||
uses: android-actions/setup-android@v3
|
||||
with:
|
||||
packages: 'platforms;android-37.0 build-tools;36.0.0'
|
||||
|
||||
# The Android SDK now comes from the self-hosted runner image, so there is no
|
||||
# setup-android step here. The image must provide it AND export ANDROID_HOME to
|
||||
# the job environment — Gradle fails with "SDK location not found" otherwise.
|
||||
# The image also has to carry the platform matching COMPILE_SDK in
|
||||
# plugins/src/main/kotlin/Versions.kt (platform packages are minor-versioned, so
|
||||
# compileSdk 37 means android-37.0) and the build-tools version AGP defaults to
|
||||
# (SdkConstants.CURRENT_BUILD_TOOLS_VERSION), since nothing sets buildToolsVersion
|
||||
# here. Both need refreshing in the image when AGP or COMPILE_SDK moves.
|
||||
- name: Configure gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
|
||||
|
||||
@@ -5,11 +5,22 @@ on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
# Private fork: actions/checkout needs contents:read to clone. Upstream is public,
|
||||
# where an empty token can still read the repo, so an empty permissions block works there and
|
||||
# fails here with `fatal: repository not found`.
|
||||
contents: read
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx4g
|
||||
# Reduced from upstream's -Xmx8g / 4 GB Kotlin daemon for the self-hosted runners.
|
||||
# Each incus container reports 48 GiB and 8 cores, so a single build has ample room —
|
||||
# but the containers are oversubscribed against their host, and two concurrent heavy
|
||||
# Gradle jobs get their daemons SIGKILLed ("the daemon has disappeared", no
|
||||
# OutOfMemoryError, no heap dump). Running the same job alone succeeds. Lower heaps
|
||||
# make two builds likelier to coexist; the real fix is sizing the containers to the
|
||||
# host. See the "Report runner capacity" step.
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=768m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx2g
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace --no-daemon -Dsonar.gradle.skipCompile=true --no-configuration-cache
|
||||
ARCH: x86_64
|
||||
DEVICE: pixel_7_pro
|
||||
@@ -19,7 +30,7 @@ env:
|
||||
jobs:
|
||||
build-apk:
|
||||
name: Build APK
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
# Secrets are not available to pull_request runs from forks, so the Maestro job below
|
||||
# cannot run for them; skip the build too, as its only consumer is that job.
|
||||
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
@@ -28,6 +39,9 @@ jobs:
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
# Only meaningful on GitHub's throwaway VMs. On a persistent self-hosted runner this
|
||||
# would delete dotnet/haskell/docker images from the host on every run.
|
||||
if: runner.environment == 'github-hosted'
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
|
||||
with:
|
||||
# This might remove tools that are actually needed, if set to "true" but frees about 6 GB
|
||||
|
||||
@@ -23,33 +23,38 @@ jobs:
|
||||
script: |
|
||||
core.setFailed("PR has been labeled with X-Blocked; it cannot be merged.");
|
||||
|
||||
community-prs:
|
||||
name: Label Community PRs
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.action == 'opened'
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Check membership
|
||||
if: github.event.pull_request.user.login != 'renovate[bot]'
|
||||
uses: tspascoal/get-user-teams-membership@b2546c5affc730fd8e3d8483ae9ad3621938c2f9 # v4.0.2
|
||||
id: teams
|
||||
with:
|
||||
username: ${{ github.event.pull_request.user.login }}
|
||||
organization: element-hq
|
||||
team: Vector Core
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN_READ_ORG }}
|
||||
- name: Add label
|
||||
if: steps.teams.outputs.isTeamMember == 'false'
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['Z-Community-PR']
|
||||
});
|
||||
# Disabled on the HealthChat fork. This job asks whether the PR author belongs to the
|
||||
# element-hq "Vector Core" team, using secrets.ELEMENT_BOT_TOKEN_READ_ORG — a secret
|
||||
# that only exists upstream. Here it fails on every PR that is opened, and there is no
|
||||
# community to label anyway. Kept commented rather than deleted so upstream changes to
|
||||
# it still conflict visibly on merge.
|
||||
# community-prs:
|
||||
# name: Label Community PRs
|
||||
# runs-on: ubuntu-latest
|
||||
# if: github.event.action == 'opened'
|
||||
# permissions:
|
||||
# pull-requests: write
|
||||
# steps:
|
||||
# - name: Check membership
|
||||
# if: github.event.pull_request.user.login != 'renovate[bot]'
|
||||
# uses: tspascoal/get-user-teams-membership@b2546c5affc730fd8e3d8483ae9ad3621938c2f9 # v4.0.2
|
||||
# id: teams
|
||||
# with:
|
||||
# username: ${{ github.event.pull_request.user.login }}
|
||||
# organization: element-hq
|
||||
# team: Vector Core
|
||||
# GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN_READ_ORG }}
|
||||
# - name: Add label
|
||||
# if: steps.teams.outputs.isTeamMember == 'false'
|
||||
# uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
# with:
|
||||
# script: |
|
||||
# github.rest.issues.addLabels({
|
||||
# issue_number: context.issue.number,
|
||||
# owner: context.repo.owner,
|
||||
# repo: context.repo.repo,
|
||||
# labels: ['Z-Community-PR']
|
||||
# });
|
||||
|
||||
close-if-fork-develop:
|
||||
name: Forbid develop branch fork contributions
|
||||
|
||||
@@ -7,11 +7,22 @@ on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
# Private fork: actions/checkout needs contents:read to clone. Upstream is public,
|
||||
# where an empty token can still read the repo, so an empty permissions block works there and
|
||||
# fails here with `fatal: repository not found`.
|
||||
contents: read
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx4g
|
||||
# Reduced from upstream's -Xmx8g / 4 GB Kotlin daemon for the self-hosted runners.
|
||||
# Each incus container reports 48 GiB and 8 cores, so a single build has ample room —
|
||||
# but the containers are oversubscribed against their host, and two concurrent heavy
|
||||
# Gradle jobs get their daemons SIGKILLed ("the daemon has disappeared", no
|
||||
# OutOfMemoryError, no heap dump). Running the same job alone succeeds. Lower heaps
|
||||
# make two builds likelier to coexist; the real fix is sizing the containers to the
|
||||
# host. See the "Report runner capacity" step.
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=768m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx2g
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace --no-daemon -Dsonar.gradle.skipCompile=true --no-configuration-cache
|
||||
|
||||
jobs:
|
||||
@@ -20,6 +31,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
# Only meaningful on GitHub's throwaway VMs. On a persistent self-hosted runner this
|
||||
# would delete dotnet/haskell/docker images from the host on every run.
|
||||
if: runner.environment == 'github-hosted'
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
|
||||
with:
|
||||
# This might remove tools that are actually needed, if set to "true" but frees about 6 GB
|
||||
@@ -63,7 +77,7 @@ jobs:
|
||||
|
||||
checkDependencies:
|
||||
name: Search for invalid dependencies
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
@@ -87,7 +101,7 @@ jobs:
|
||||
# Code checks
|
||||
konsist:
|
||||
name: Konsist tests
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('check-konsist-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-konsist-develop-{0}', github.sha) || format('check-konsist-{0}', github.ref) }}
|
||||
@@ -128,12 +142,21 @@ jobs:
|
||||
|
||||
compose:
|
||||
name: Compose tests
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('check-compose-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-compose-develop-{0}', github.sha) || format('check-compose-{0}', github.ref) }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
# Records the container's real limits so heap settings can be read against them
|
||||
# instead of guessed at. Mirrors healthchat-release-playstore.yml.
|
||||
- name: Report runner capacity
|
||||
if: runner.environment == 'self-hosted'
|
||||
run: |
|
||||
free -h; nproc; df -h .
|
||||
cat /sys/fs/cgroup/memory.max 2>/dev/null \
|
||||
|| cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null \
|
||||
|| echo "no cgroup memory limit visible"
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
# Ensure we are building the branch and not the branch after being merged on develop
|
||||
@@ -162,7 +185,7 @@ jobs:
|
||||
|
||||
lint:
|
||||
name: Android lint check
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('check-lint-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-lint-develop-{0}', github.sha) || format('check-lint-{0}', github.ref) }}
|
||||
@@ -207,7 +230,7 @@ jobs:
|
||||
|
||||
detekt:
|
||||
name: Detekt checks
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('check-detekt-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-detekt-develop-{0}', github.sha) || format('check-detekt-{0}', github.ref) }}
|
||||
@@ -248,7 +271,7 @@ jobs:
|
||||
|
||||
ktlint:
|
||||
name: Ktlint checks
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('check-ktlint-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-ktlint-develop-{0}', github.sha) || format('check-ktlint-{0}', github.ref) }}
|
||||
@@ -331,6 +354,10 @@ jobs:
|
||||
name: Run zizmor
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# A job-level block replaces the workflow-level one, so contents:read has to be
|
||||
# repeated here or checkout fails on this private fork.
|
||||
contents: read
|
||||
actions: read # Required for zizmor to read workflow files.
|
||||
security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files.
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
@@ -5,11 +5,22 @@ on:
|
||||
pull_request:
|
||||
types: [ labeled ]
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
# Private fork: actions/checkout needs contents:read to clone. Upstream is public,
|
||||
# where an empty token can still read the repo, so an empty permissions block works there and
|
||||
# fails here with `fatal: repository not found`.
|
||||
contents: read
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx4g -Dsonar.gradle.skipCompile=true
|
||||
# Reduced from upstream's -Xmx8g / 4 GB Kotlin daemon for the self-hosted runners.
|
||||
# Each incus container reports 48 GiB and 8 cores, so a single build has ample room —
|
||||
# but the containers are oversubscribed against their host, and two concurrent heavy
|
||||
# Gradle jobs get their daemons SIGKILLed ("the daemon has disappeared", no
|
||||
# OutOfMemoryError, no heap dump). Running the same job alone succeeds. Lower heaps
|
||||
# make two builds likelier to coexist; the real fix is sizing the containers to the
|
||||
# host. See the "Report runner capacity" step.
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=768m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx2g -Dsonar.gradle.skipCompile=true
|
||||
CI_GRADLE_ARG_PROPERTIES: --no-configuration-cache
|
||||
|
||||
jobs:
|
||||
@@ -19,11 +30,14 @@ jobs:
|
||||
pull-requests: write
|
||||
contents: write
|
||||
name: Record screenshots on branch ${{ github.event.pull_request.head.ref || github.ref_name }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
if: github.event_name == 'workflow_dispatch' || github.event.label.name == 'Record-Screenshots'
|
||||
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
# Only meaningful on GitHub's throwaway VMs. On a persistent self-hosted runner this
|
||||
# would delete dotnet/haskell/docker images from the host on every run.
|
||||
if: runner.environment == 'github-hosted'
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
|
||||
with:
|
||||
# This might remove tools that are actually needed, if set to "true" but frees about 6 GB
|
||||
|
||||
@@ -7,24 +7,38 @@ on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
# Private fork: actions/checkout needs contents:read to clone. Upstream is public,
|
||||
# where an empty token can still read the repo, so an empty permissions block works there and
|
||||
# fails here with `fatal: repository not found`.
|
||||
contents: read
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx4g
|
||||
# Reduced from upstream's -Xmx8g / 4 GB Kotlin daemon for the self-hosted runners.
|
||||
# Each incus container reports 48 GiB and 8 cores, so a single build has ample room —
|
||||
# but the containers are oversubscribed against their host, and two concurrent heavy
|
||||
# Gradle jobs get their daemons SIGKILLed ("the daemon has disappeared", no
|
||||
# OutOfMemoryError, no heap dump). Running the same job alone succeeds. Lower heaps
|
||||
# make two builds likelier to coexist; the real fix is sizing the containers to the
|
||||
# host. See the "Report runner capacity" step.
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=768m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -Dkotlin.daemon.jvm.options=-Xmx2g
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace --warn -Dsonar.gradle.skipCompile=true --no-configuration-cache
|
||||
GROUP: ${{ format('sonar-{0}', github.ref) }}
|
||||
|
||||
jobs:
|
||||
sonar:
|
||||
name: Sonar Quality Checks
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ format('sonar-{0}', github.ref) }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/develop' }}
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
# Only meaningful on GitHub's throwaway VMs. On a persistent self-hosted runner this
|
||||
# would delete dotnet/haskell/docker images from the host on every run.
|
||||
if: runner.environment == 'github-hosted'
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
|
||||
with:
|
||||
# This might remove tools that are actually needed, if set to "true" but frees about 6 GB
|
||||
|
||||
@@ -7,24 +7,53 @@ on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
# Private fork: actions/checkout needs contents:read to clone. Upstream is public,
|
||||
# where an empty token can still read the repo, so an empty permissions block works there and
|
||||
# fails here with `fatal: repository not found`.
|
||||
contents: read
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx7g -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options=-Xmx2g -XX:+UseG1GC
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace -Dsonar.gradle.skipCompile=true --no-configuration-cache
|
||||
# Reduced from upstream's -Xmx8g / 4 GB Kotlin daemon for the self-hosted runners.
|
||||
# Each incus container reports 48 GiB and 8 cores, so a single build has ample room —
|
||||
# but the containers are oversubscribed against their host, and two concurrent heavy
|
||||
# Gradle jobs get their daemons SIGKILLed ("the daemon has disappeared", no
|
||||
# OutOfMemoryError, no heap dump). Running the same job alone succeeds. Lower heaps
|
||||
# make two builds likelier to coexist; the real fix is sizing the containers to the
|
||||
# host. See the "Report runner capacity" step.
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx6g -XX:MaxMetaspaceSize=768m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options=-Xmx2g -XX:+UseG1GC
|
||||
# --max-workers caps how many test tasks run at once. build.gradle.kts sets
|
||||
# maxParallelForks = cores/2 and screenshot tests fork at maxHeapSize=2g, so on these
|
||||
# 8-core containers the default (workers = cores = 8) allows 8 x 4 x 2g = 64 GB of test
|
||||
# JVMs against a 48 GiB cgroup limit, with no swap — the daemon gets OOM-killed and
|
||||
# Gradle reports "the daemon has disappeared". GitHub's 4-core hosted runners reach only
|
||||
# 2 x 2 x 2g = 16 GB and additionally have the 8 GB swapfile added above.
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace -Dsonar.gradle.skipCompile=true --no-configuration-cache --max-workers=4
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: Runs unit tests
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('unit-tests-{0}', github.ref) }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
# Records the container's real limits so heap settings can be read against them
|
||||
# instead of guessed at. Mirrors healthchat-release-playstore.yml.
|
||||
- name: Report runner capacity
|
||||
if: runner.environment == 'self-hosted'
|
||||
run: |
|
||||
free -h; nproc; df -h .
|
||||
cat /sys/fs/cgroup/memory.max 2>/dev/null \
|
||||
|| cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null \
|
||||
|| echo "no cgroup memory limit visible"
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
# Only meaningful on GitHub's throwaway VMs. On a persistent self-hosted runner this
|
||||
# would delete dotnet/haskell/docker images from the host on every run.
|
||||
if: runner.environment == 'github-hosted'
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
|
||||
with:
|
||||
# This might remove tools that are actually needed, if set to "true" but frees about 6 GB
|
||||
@@ -41,6 +70,9 @@ jobs:
|
||||
# Increase swapfile size to prevent screenshot tests getting terminated
|
||||
# https://github.com/actions/runner-images/discussions/7188#discussioncomment-6750749
|
||||
- name: 💽 Increase swapfile size
|
||||
# /mnt/swapfile is a GitHub runner-image path and this needs passwordless sudo,
|
||||
# so it only applies to the hosted VMs.
|
||||
if: runner.environment == 'github-hosted'
|
||||
run: |
|
||||
sudo swapoff -a
|
||||
sudo fallocate -l 8G /mnt/swapfile
|
||||
@@ -112,8 +144,15 @@ jobs:
|
||||
echo "---" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# https://github.com/codecov/codecov-action
|
||||
# This fork has no CODECOV_TOKEN, and Codecov rejects tokenless uploads from private
|
||||
# repositories ("Token required - not valid tokenless upload"). With
|
||||
# fail_ci_if_error: true that failed the whole job *after* the tests had passed, so
|
||||
# skip the upload unless a token is configured. Adding the secret re-enables it.
|
||||
- name: ☂️ Upload coverage reports to codecov
|
||||
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
|
||||
if: env.CODECOV_TOKEN != ''
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@@ -2,7 +2,11 @@ name: Validate Git LFS
|
||||
|
||||
on: [pull_request, merge_group]
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
# Private fork: actions/checkout needs contents:read to clone. Upstream is public,
|
||||
# where an empty token can still read the repo, so an empty permissions block works there and
|
||||
# fails here with `fatal: repository not found`.
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
Reference in New Issue
Block a user