Repository navigation
tech: Run the test suite without repository secrets - #397
Merged
Merged
Conversation
Pull requests from forks never receive secrets, so setupKey.sh wrote an empty private key and the suite aborted with signal 6 the moment a test force-unwrapped an account built from it. That took every later suite with it, so outside contributions could not get a usable CI signal at all, and a fresh clone could not run the tests without being handed the key. Almost nothing actually needed that key. Three separate needs were hidden behind it: paying for gas, having a specific key to derive an address or produce a deterministic signature, and simply naming an address on chain. Only the first is secret. Split them. Address-only tests use the funded account's address, which is public and now committed. Signing and identity tests use a throwaway key, also committed — the well-known Anvil account #0, which holds nothing. The funded key moves to the TESTS_PRIVATEKEY environment variable, so the generated file and setupKey.sh are gone, and it is read straight from the environment CI already sets. That leaves one test that spends Ether. It skips when the key is absent rather than failing. Two other suites held accounts built from the key that were never used at all, which is most of why the abort had such a wide blast radius; those are deleted. The zkSync signing test now signs with the throwaway key, so its expected value is regenerated. It also recovers the signer from the EIP-712 digest and asserts it matches, so the hash pins the encoding rather than just recording whatever the code happened to emit. CI also runs on pushes to develop, since a fork's pull request cannot exercise the funded test before it merges.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the suite runnable with no credentials, so pull requests from forks get a real CI signal and a fresh clone can run
swift testimmediately.Unblocks #392, which is currently red through no fault of its own.
The problem
GitHub never gives repository secrets to pull requests from forks.
setupKey.shtherefore wroteprivateKey = "", which compiles — so this was never a build failure, despite appearances. The suite got as far as the first test that force-unwrapped an account built from that key and died:Signal 6 is an abort, and it takes the whole test process with it, so every suite after it never ran. Same pattern as the Linux abort in #395: what looks like a couple of failing tests is actually most of the suite never executing.
What actually needed the key
Three different needs were hidden behind one secret. Only the first is secret at all:
testEthSendRawTransactiontestLoadAccountAndAddress,…Multiple, zkSync signing testgetTransactionCount×2,getBalanceTwo further suites —
OffchainLookupTestsandEthereumClientZKSyncTests— built accounts from the key and never used them. That is most of why the abort had such a wide blast radius.Changes
TESTS_PRIVATEKEYenvironment variable.setupKey.shand the generatedTestConfig_private.swiftare deleted; CI already exported this variable alongside running the script.TestConfig.signingPrivateKey— the well-known Anvil/Hardhat account #0, public by design and holding nothing. Used wherever a key is needed but funds are not.TestConfig.publicKey, unchanged in value. It was already insetupKey.shin the clear; an address is not a secret, and the nonce and log fixtures are its on-chain history.testEthSendRawTransactioncallsrequireFundedPrivateKey(), which throwsXCTSkipwith an explanation when the variable is absent.OffchainLookupTestsandEthereumClientZKSyncTests.develop, since a fork's PR cannot exercise the funded test before it merges.🤖 Generated with Claude Code