55 branches : [main]
66 pull_request :
77 paths :
8- - " packages/ats/**"
9- - " apps/ats/**"
8+ - " packages/ats/contracts/**"
109 - " package.json"
1110 - " .github/workflows/*ats*.yaml"
1211 workflow_dispatch :
@@ -20,35 +19,12 @@ permissions:
2019
2120jobs :
2221 test-ats :
23- name : testing
22+ name : contracts scripts tests
2423 runs-on : token-studio-linux-large
2524 timeout-minutes : 45
2625 env :
2726 CONTRACT_SIZER_RUN_ON_COMPILE : " false"
2827 REPORT_GAS : " false"
29- CLIENT_PRIVATE_KEY_ECDSA_1 : ${{ secrets.CLIENT_PRIVATE_KEY_ECDSA_1 }}
30- CLIENT_PUBLIC_KEY_ECDSA_1 : ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_1 }}
31- CLIENT_ACCOUNT_ID_ECDSA_1 : " 0.0.1328"
32- CLIENT_EVM_ADDRESS_ECDSA_1_CORRECT : " 0x97C50bb12E1C6284cF2855cdba95c5D60AEE44CF"
33- CLIENT_EVM_ADDRESS_ECDSA_1 : " 0x0000000000000000000000000000000000000530"
34- CLIENT_PRIVATE_KEY_ECDSA_2 : ${{ secrets.CLIENT_PRIVATE_KEY_ECDSA_2 }}
35- CLIENT_PUBLIC_KEY_ECDSA_2 : ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_2 }}
36- CLIENT_ACCOUNT_ID_ECDSA_2 : " 0.0.2168740"
37- CLIENT_EVM_ADDRESS_ECDSA_2 : " 0x00000000000000000000000000000000002117A4"
38- FACTORY_ADDRESS : " 0.0.5480051"
39- RESOLVER_ADDRESS : " 0.0.5479997"
40- FIREBLOCKS_HEDERA_ACCOUNT_ID : " 0.0.2168740"
41- FIREBLOCKS_HEDERA_PUBLIC_KEY : ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_2 }}
42- DFNS_HEDERA_ACCOUNT_ID : " 0.0.2168740"
43- DFNS_WALLET_PUBLIC_KEY : ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_2 }}
44- AWS_KMS_HEDERA_ACCOUNT_ID : " 0.0.4394946"
45- AWS_KMS_HEDERA_PUBLIC_KEY : " 302d300706052b8104000a03220003ee815bb9b5e53f5dbe7264a77e586127dfcb75da8c1246f5aa6ededdb13e6c21"
46- REACT_APP_MIRROR_NODE : " https://testnet.mirrornode.hedera.com/api/v1/"
47- REACT_APP_RPC_NODE : " https://testnet.hashio.io/api"
48- REACT_APP_RESOLVER : " 0.0.5479997"
49- REACT_APP_FACTORY : " 0.0.5480051"
50- REACT_APP_SHOW_DISCLAIMER : " true"
51- CODECOV_TOKEN : ${{ secrets.CODECOV_TOKEN }}
5228
5329 steps :
5430 - name : Harden Runner
@@ -65,33 +41,164 @@ jobs:
6541 node-version-file : .nvmrc
6642 cache : " npm"
6743
44+ # Shared dependency cache across every job in this workflow (and matched by the other ATS
45+ # workflows on the same key), so node_modules is restored instead of reinstalled. On a hit
46+ # the install below is skipped entirely.
47+ - name : Restore dependencies from cache
48+ id : deps-cache
49+ uses : actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
50+ with :
51+ path : |
52+ node_modules
53+ */*/node_modules
54+ */*/*/node_modules
55+ ~/.npm
56+ key : ${{ runner.os }}-deps-${{ hashFiles('package-lock.json') }}
57+
58+ # --ignore-scripts skips the contracts `prepare` hook (a *production* `hardhat compile`).
59+ # Every job here recompiles in test/coverage mode anyway and regenerates the gitignored
60+ # resolver registry as part of that compile, so the prepare compile is pure duplicated work.
6861 - name : Install dependencies
69- run : npm run ats:install
70-
71- # BBND-1766: `atsRegistry.generated.ts` is gitignored and regenerated
72- # by the contracts package's `prepare` script during `npm ci`. This
73- # step is the clean-checkout guard for that contract — if the file is
74- # missing after install, `prepare` regressed and every downstream
75- # build / test step would fail with a confusing module-not-found.
76- - name : Verify auto-generated registry produced by prepare hook
62+ if : steps.deps-cache.outputs.cache-hit != 'true'
63+ run : npm ci --ignore-scripts
64+
65+ # Contracts integration tests run under coverage in the parallel `coverage-ats` matrix below
66+ # (which doubles as their gate), so this job only runs the scripts/* suite that coverage does
67+ # not exercise. SDK and web are deprecated and no longer tested here.
68+ #
69+ # The scripts suite deploys the system and exercises test-only facets (EvmAccessors,
70+ # MockDiamondCut, …), so it needs a TEST-MODE compile — which also regenerates the test-mode
71+ # resolver registry — before the run. `--force` is mandatory: without it Hardhat sees no
72+ # source change and skips, leaving a registry with no key for EvmAccessorsFacet.
73+ - name : Run contracts scripts tests
74+ working-directory : packages/ats/contracts
75+ env :
76+ ATS_TEST_MODE : " true"
7777 run : |
78- REGISTRY_PATH="packages/ats/contracts/scripts/domain/atsRegistry.generated.ts"
79- if [[ ! -f "${REGISTRY_PATH}" ]]; then
80- echo "::error::${REGISTRY_PATH} missing after npm ci. The contracts package's 'prepare' script (hardhat compile) likely regressed."
81- exit 1
82- fi
83- if ! grep -q "^export const FACET_REGISTRY" "${REGISTRY_PATH}"; then
84- echo "::error::${REGISTRY_PATH} missing FACET_REGISTRY export — generator produced a malformed file."
85- exit 1
86- fi
87- echo "✓ ${REGISTRY_PATH} auto-regenerated by prepare hook"
88-
89- - name : Build ATS packages
90- run : npm run ats:build
91-
92- - name : Run ATS tests
93- run : npm run ats:test:ci
94-
95- - name : Upload coverage report
96- if : ${{ !cancelled() && always() }}
78+ npm run compile:force
79+ npm run test:scripts
80+
81+ # Contracts coverage is sharded across parallel runners: solidity-coverage re-instruments and
82+ # recompiles per shard (unavoidable on Hardhat 2), but each shard runs on its own runner so the
83+ # ~3 min compile overlaps instead of serializing. Each shard runs the mega-asset entry once for
84+ # its `i % SHARD_TOTAL` slice plus a round-robined share of the standalone suites, computed by
85+ # scripts/tools/coverage-shard/planShard.ts. Shards upload their lcov as artifacts; the
86+ # merge-coverage job below combines them into a single report and uploads it once to Codecov.
87+ coverage-ats :
88+ name : coverage (shard ${{ matrix.shard }})
89+ runs-on : token-studio-linux-large
90+ timeout-minutes : 45
91+ strategy :
92+ fail-fast : false
93+ matrix :
94+ # Keep this list's length equal to SHARD_TOTAL below (indices 0..N-1).
95+ shard : [0, 1, 2, 3]
96+ env :
97+ CONTRACT_SIZER_RUN_ON_COMPILE : " false"
98+ REPORT_GAS : " false"
99+ SHARD_INDEX : ${{ matrix.shard }}
100+ SHARD_TOTAL : " 4"
101+
102+ steps :
103+ - name : Harden Runner
104+ uses : step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
105+ with :
106+ egress-policy : audit
107+
108+ - name : Checkout repository
109+ uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
110+
111+ - name : Setup NodeJS Environment
112+ uses : actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
113+ with :
114+ node-version-file : .nvmrc
115+ cache : " npm"
116+
117+ - name : Restore dependencies from cache
118+ id : deps-cache
119+ uses : actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
120+ with :
121+ path : |
122+ node_modules
123+ */*/node_modules
124+ */*/*/node_modules
125+ ~/.npm
126+ key : ${{ runner.os }}-deps-${{ hashFiles('package-lock.json') }}
127+
128+ - name : Install dependencies
129+ if : steps.deps-cache.outputs.cache-hit != 'true'
130+ run : npm ci --ignore-scripts
131+
132+ - name : Run contracts coverage shard
133+ run : npm run test:coverage:shard --workspace=packages/ats/contracts
134+
135+ - name : Upload coverage shard artifact
136+ if : ${{ !cancelled() }}
137+ uses : actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
138+ with :
139+ name : coverage-shard-${{ matrix.shard }}
140+ path : packages/ats/contracts/coverage/lcov.info
141+ if-no-files-found : error
142+ retention-days : 1
143+
144+ # Merge the per-shard lcov reports into a single report and upload it once to Codecov — matching
145+ # the local `npm run test:coverage` single report, instead of uploading partial per-shard pieces.
146+ # Runs only when every shard succeeded, so the merged report is complete.
147+ merge-coverage :
148+ name : merge coverage + upload
149+ needs : coverage-ats
150+ runs-on : token-studio-linux-large
151+ timeout-minutes : 15
152+ env :
153+ CODECOV_TOKEN : ${{ secrets.CODECOV_TOKEN }}
154+
155+ steps :
156+ - name : Harden Runner
157+ uses : step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
158+ with :
159+ egress-policy : audit
160+
161+ - name : Checkout repository
162+ uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
163+
164+ - name : Setup NodeJS Environment
165+ uses : actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
166+ with :
167+ node-version-file : .nvmrc
168+ cache : " npm"
169+
170+ - name : Restore dependencies from cache
171+ id : deps-cache
172+ uses : actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
173+ with :
174+ path : |
175+ node_modules
176+ */*/node_modules
177+ */*/*/node_modules
178+ ~/.npm
179+ key : ${{ runner.os }}-deps-${{ hashFiles('package-lock.json') }}
180+
181+ - name : Install dependencies
182+ if : steps.deps-cache.outputs.cache-hit != 'true'
183+ run : npm ci --ignore-scripts
184+
185+ - name : Download all coverage shard artifacts
186+ uses : actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
187+ with :
188+ pattern : coverage-shard-*
189+ path : coverage-shards
190+
191+ # Sum line/function/branch hits across the disjoint shards into one lcov, written to the same
192+ # path a local single-run coverage produces, so the Codecov upload is identical to local. Uses
193+ # the in-repo merger (preserves function coverage, which lcov-result-merger drops; no
194+ # runtime-fetched dependency).
195+ - name : Merge shard lcov reports
196+ working-directory : packages/ats/contracts
197+ run : npm run coverage:merge -- coverage/lcov.info "${GITHUB_WORKSPACE}/coverage-shards"
198+
199+ - name : Upload merged coverage to Codecov
97200 uses : codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v5.4.0
201+ with :
202+ token : ${{ secrets.CODECOV_TOKEN }}
203+ files : packages/ats/contracts/coverage/lcov.info
204+ disable_search : true
0 commit comments