Skip to content

ci(examples): fund each Devnet run from one faucet grant instead of a secret - #41

Merged
isaacdoidge merged 2 commits into
masterfrom
ci/examples-faucet-funding
Nov 4, 2026
Merged

isaacdoidge merged 2 commits into
masterfrom
ci/examples-faucet-funding

Conversation

@isaacdoidge

Copy link
Copy Markdown
Collaborator

What

The scheduled Examples workflow (#39) no longer needs the SUPRA_EXAMPLES_PRIVATE_KEY repository secret, which would
have to be replaced after every Devnet reset. Each run funds itself from the Devnet faucet with one request and runs
the examples from that account.

Changes

  • examples/faucet_funder.py (python -m examples.faucet_funder; not an example):
    • Generates a throwaway Ed25519 account and funds it with one faucet grant, using the examples' bounded TryLater
      retry and wait.
    • Prints only the private key on stdout, as one line; the address and progress go to stderr.
    • Refuses Mainnet.
  • .github/workflows/examples.yaml:
    • No secrets. reference; the key-present check and the skip notice are removed.
    • One step runs key="$(uv run python -m examples.faucet_funder)", masks it with ::add-mask::, and runs
      SUPRA_EXAMPLES_PRIVATE_KEY="$key" make examples EXAMPLES_EXCLUDE=faucet.
    • faucet.py is left out in CI: its own request would be a second faucet request from the runner's IP address,
      and the funding step makes the same SDK faucet call.
    • Unchanged: daily and workflow_dispatch triggers only, contents: read, persist-credentials: false, pinned
      actions, uv 0.13.7, UV_FROZEN=1 and UV_NO_SYNC=1 on the step that holds the key, and the concurrency group,
      whose comment now gives its reason as the faucet's per-IP limit.
  • Makefile: make examples takes EXAMPLES_EXCLUDE to leave examples out.
  • examples/README.md: without a key each example makes its own faucet request, which Devnet's per-IP limit can
    refuse. To run all of them against Devnet, set a funded key or create one from a single grant:
    SUPRA_EXAMPLES_PRIVATE_KEY="$(uv run python -m examples.faucet_funder)" make examples EXAMPLES_EXCLUDE=faucet.
    The CI workflow is described.

Why one request is enough

  • Devnet's faucet grants 5,000 SUPRA per request, as listed on Devnet's API page. A full run moves about 325 SUPRA
    from the funding account.
  • The node's own limits (3,600 s cooldown, 20 grants a day, refusal at 10,000 SUPRA) apply per receiving address,
    and each run funds a new address.
  • Devnet also limits faucet requests per client IP address in front of the node, across all faucet endpoints. One
    request per run stays well within a limit of that kind; the limit's value is not published.

Checks

  • make fmt-check, make lint, make typecheck (45 files), make build, actionlint: pass.
  • make test-unit: 394 tests, 26 node-backed skipped. One failure, which master has too and which a separate PR
    fixes (test_a_node_without_the_route_raises_api_error, from feat(client)!: typed HTTP errors, a configurable timeout, opt-in GET retries and faucet TryLater #35 and feat(rest): add account_history to master, iter_account_fa_transactions, and one cursor rule #40 merging). New offline tests check that the
    funder's stdout is exactly one key line, that its progress goes to stderr, and that it refuses Mainnet.
  • On a fresh supra_node_v12.0.0.rc7 localnet (500 SUPRA per faucet grant), the workflow's command (funder, then
    make examples EXAMPLES_EXCLUDE=faucet with its key) ran four times:
    • Three runs: all 13 examples passed, and the output contains no key.
    • The first run, a minute after the localnet started, failed from simulate_transfer_coin on. A funding transfer
      from the shared account stayed pending across the localnet's first epoch change, and every later example was
      refused because it reused that sequence number. A localnet changes epoch within minutes of starting; Devnet's
      epochs are longer. A run that hits it fails rather than passing.
  • The workflow was not run, because it transacts on Devnet.

🤖 Generated with Claude Code

isaacdoidge and others added 2 commits November 4, 2026 11:13
… secret

The scheduled Examples workflow no longer reads a repository secret. Each run
generates a throwaway account with `python -m examples.faucet_funder`, which
makes one faucet request (with the examples' bounded TryLater retry), waits for
the balance, prints only the private key on stdout and everything else on
stderr, and refuses Mainnet. The workflow masks the key with `::add-mask::` and
runs `make examples EXAMPLES_EXCLUDE=faucet` from that account, so a run makes
one faucet request from the runner's IP address. `faucet.py` is excluded in CI
because its own request would be a second one.

`make examples` takes `EXAMPLES_EXCLUDE` to leave examples out. The examples
README describes the funder and the workflow.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@isaacdoidge
isaacdoidge merged commit 6e5308c into master Nov 4, 2026
5 checks passed
@isaacdoidge
isaacdoidge deleted the ci/examples-faucet-funding branch November 4, 2026 01:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant