-
Notifications
You must be signed in to change notification settings - Fork 77
191 lines (173 loc) · 8.94 KB
/
Copy pathanalyze_and_test.yml
File metadata and controls
191 lines (173 loc) · 8.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
name: Analyze and Test
on:
pull_request:
branches:
- main
- develop
# Docs-only PRs skip both jobs entirely. Safe because develop has no
# required status checks (verified via the API) — a skipped run can't
# strand a PR on "Expected — waiting". If checks are ever made required,
# this needs the paths-filter + always-green sentinel pattern instead.
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- '.gitignore'
- '.git-blame-ignore-revs'
- '.github/ISSUE_TEMPLATE/**'
# The funded Payjoin fixture spends from shared testnet wallets. It does not
# run for the concurrent develop stack; workflow_dispatch lets a reviewer run
# it for an arbitrary branch.
workflow_dispatch:
# Checkout + tests only; no writes to the repo via the token.
permissions:
contents: read
# Cancel superseded runs on the same PR — these builds are heavy (Rust FRB
# crates + Flutter SDK + Linux GTK app + integration tests), so don't run stale
# commits to completion when newer ones are pushed.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Two independent jobs split at the FRB boundary. `checks` (analyze + fix +
# format + unit tests) never compiles the Rust FRB crates — unit tests run on
# the Dart VM against the bindings' Dart side only — so it reports in ~11min.
# `integration` builds and launches the real Linux GTK app (Rust + GTK), the
# ~28min long pole, in parallel. Both pay the same setup prefix (composite
# action below); build_runner (~6.5min) dominates it — caching its output is
# the known follow-up. Neither job `needs:` the other on purpose: the split
# exists so the fast signal never waits for the slow one.
jobs:
checks:
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@v7
# Kept deliberately: a local .dart_tool can reach 16GB and a stock x64
# runner has ~21GB free, so dropping this risks turning every PR red on
# "No space left on device". The setup action logs `df -h` — only drop
# this once a few runs prove comfortable headroom.
- name: Free disk space
# Pinned to a commit SHA (not the mutable v1.3.1 tag): third-party action
# on a runner that can hold PR test secrets — a retag must not run here.
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
with:
tool-cache: true
android: true
dotnet: true
haskell: true
large-packages: true
swap-storage: false
# The gates below reference steps.setup.outcome — if this `id` is ever
# renamed, the expression silently evaluates to '' and every check
# SKIPS (job goes green with nothing run). Keep id and gates in sync.
- name: Flutter setup
id: setup
uses: ./.github/actions/flutter-setup
# The four static checks are gated on `!cancelled()` + setup success
# instead of the implicit success(): one CI run surfaces ALL static
# failures instead of stopping at the first (they're independent and
# cheap, ~1.5min combined). `!cancelled()` (not `always()`) so a
# superseded run cancelled by the concurrency group stops immediately.
# Each gate is a makefile target so the definition lives in one place; `make checks` runs this whole job locally.
- name: Linter shouldn't raise errors, warnings or infos
if: ${{ !cancelled() && steps.setup.outcome == 'success' }}
run: make analyze
- name: bull_ui import boundary (coins/ui imports only package:bull_ui)
if: ${{ !cancelled() && steps.setup.outcome == 'success' }}
run: make bull-ui-check
- name: dart fix should have nothing to suggest
if: ${{ !cancelled() && steps.setup.outcome == 'success' }}
run: make fix-check
# The gate's filter regex and pipefail rationale live in the makefile's format-check target; the staged-files variant in .git_hooks/pre-commit keeps its own copy of the regex.
- name: dart format should have nothing to change
if: ${{ !cancelled() && steps.setup.outcome == 'success' }}
run: make format-check
# Default success() gate on purpose: if any static check above is red,
# skip the tests — the PR needs another push anyway.
- name: Unit tests must pass
run: make unit-test
integration:
# arm64: free 4-vCPU runners for public repos, native arm execution — the
# Rust FRB compile is exactly the workload that benefits. If this arch
# surfaces a toolchain wart, revert this job to ubuntu-24.04 + the
# jlumbroso free-disk-space step (see checks job) in one commit.
runs-on: ubuntu-24.04-arm
timeout-minutes: 60
steps:
- name: Checkout Repository
uses: actions/checkout@v7
# This job builds the FRB Rust crates, the Flutter SDK toolchain and the
# Linux desktop app on one runner. The arm64 partner image is leaner
# than x64 (more free space, and the x64-oriented free-disk-space action
# doesn't apply), so reclaim the few big preinstalled dirs inline;
# `|| true` because they may not exist on this image. The setup action
# logs `df -h` to confirm headroom.
- name: Free disk space (inline, arch-agnostic)
run: |
sudo rm -rf /usr/local/lib/android /opt/hostedtoolcache /usr/share/dotnet /opt/ghc || true
df -h /
# cargokit builds the FRB crates via `rustup run stable cargo`; the
# leaner arm64 partner image may lack rustup (the x64 image ships it).
# Idempotent: installs rustup if absent, then ensures the stable
# toolchain exists either way (newer rustup does not auto-install
# toolchains on `rustup run`).
- name: Ensure rustup + stable toolchain
run: |
if ! command -v rustup >/dev/null 2>&1; then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
else
rustup toolchain install stable --profile minimal
fi
- name: Flutter setup
uses: ./.github/actions/flutter-setup
with:
cargo-cache: 'true'
# Compiler cache for the FRB Rust crates (the dominant cost of the app
# build), backed by the GitHub Actions cache. Pinned to a commit SHA:
# third-party action on a runner that holds PR test secrets.
# RUSTC_WRAPPER is exported at the test step below; cargokit's cargo
# inherits it from the environment.
- name: Setup sccache
uses: Mozilla-Actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
- name: Install Linux desktop for integration tests
run: |
sudo apt-get update
sudo apt-get install -y \
clang lld cmake ninja-build pkg-config \
libgtk-3-dev liblzma-dev libstdc++-12-dev \
libsecret-1-dev libsecret-tools libcurl4-openssl-dev \
dbus gnome-keyring \
xdg-desktop-portal xdg-desktop-portal-gtk \
libsqlite3-dev xvfb xauth
# The tests build and launch the real Linux GTK app, which needs a
# display to init even though the tests themselves render nothing —
# on a headless runner the app aborts at startup ("log reader
# stopped unexpectedly / Unable to start the app on the device").
# xvfb-run gives it a virtual X server. dbus-run-session + an
# unlocked gnome-keyring provide the Secret Service flutter_secure_storage needs.
# Tests read the mnemonics via Platform.environment, so the secrets are
# exported as real env vars (not a .env file, which nothing loads). When a
# secret is unset (e.g. on forks) the var is empty and the funded-testnet
# groups skip themselves — "use the mnemonic if available".
- name: Integration tests (Linux desktop)
env:
TEST_ALICE_MNEMONIC: ${{ secrets.ENV_TEST_ALICE_MNEMONIC }}
TEST_BOB_MNEMONIC: ${{ secrets.ENV_TEST_BOB_MNEMONIC }}
# The fixture spends from these two shared wallets. It runs as a final
# delivery gate on PRs to main, rather than for every develop PR in a
# stack, and can still be run manually for an arbitrary branch.
RUN_FUNDED_PAYJOIN_TEST: ${{ github.base_ref == 'main' || github.event_name == 'workflow_dispatch' }}
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: sccache
# sccache cannot cache incremental compilation artifacts; disabling
# incremental makes every rustc invocation cacheable (and is the
# standard sccache-in-CI pairing — CI never reuses incremental state
# anyway).
CARGO_INCREMENTAL: "0"
run: |
xvfb-run -a dbus-run-session -- bash -c '
echo "" | gnome-keyring-daemon --unlock --daemonize --components=secrets
make integration-test
'