Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/analyze_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ on:
- '.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:
Expand Down Expand Up @@ -169,6 +173,10 @@ jobs:
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
Expand Down
17 changes: 8 additions & 9 deletions integration_test/payjoin_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ Future<void> main({bool isInitialized = false}) async {
receiverMnemonic != null &&
receiverMnemonic.isNotEmpty &&
senderMnemonic != null &&
senderMnemonic.isNotEmpty;
senderMnemonic.isNotEmpty &&
Platform.environment['RUN_FUNDED_PAYJOIN_TEST'] == 'true';
const fixtureSkip =
'requires TEST_ALICE_MNEMONIC and TEST_BOB_MNEMONIC (funded testnet wallets)';
'requires a PR to main or a manually dispatched CI run with funded testnet wallets';

// Belongs to this file's own Bull.init above, not to the fixtures, so it
// stays at the root scope and runs even when the funded group is skipped.
Expand Down Expand Up @@ -150,13 +151,11 @@ Future<void> main({bool isInitialized = false}) async {
// are individually skipped still runs its setUpAll and tearDownAll, whereas
// a skipped group runs neither. Verified against package:test 1.31.
//
// That distinction is what made every fork PR red. GitHub withholds secrets
// from pull_request runs on forks, so TEST_ALICE_MNEMONIC/TEST_BOB_MNEMONIC
// expand to the empty string — set but empty. The tests below skipped
// correctly, yet this setUpAll still ran, and createFromMnemonic rejected a
// 1-word mnemonic. Because gen_all_test.dart calls each file's main()
// without wrapping it in a group, the failure landed on the root scope of
// the aggregated suite and took down the whole integration job.
// This also keeps shared funded wallets out of concurrent pull-request jobs.
// Every such job otherwise derives the same BIP84 account and broadcasts
// consolidation transactions from the same UTXOs, causing RBF conflicts.
// The workflow enables this group for delivery PRs to main or manual runs,
// not for every branch in a concurrent develop stack.
//
// Scoping the hooks to the group also stops them leaking into the other
// seven aggregated files, which previously inherited this setUp and paid a
Expand Down
Loading