1515# EVERY suite (GitLab: the `base_changes` anchor).
1616# * Otherwise only the suites whose own directory changed run.
1717# * GitLab's `splunk_base_build_rule` -- a change to splunk_base also runs the
18- # other three splunk suites, which import its test helpers -- is not ported
19- # here because no splunk suite runs yet. It lands with them in phase 2
20- # (STAC-25531).
18+ # other three splunk suites, which import its test helpers.
2119# * push / workflow_dispatch run everything (GitLab: `master_branch`,
2220# `release_branch`).
2321#
24- # Writes three arrays to $GITHUB_OUTPUT for `fromJson()` in a matrix:
25- # checks -- suites that need no credentials
26- # private_checks -- suites that install from the private GitLab PyPI
27- # index, and are cleared to run on this event
28- # deferred_private_checks -- private-index suites withheld from this event
29- # (always empty outside pull requests)
22+ # Writes two arrays to $GITHUB_OUTPUT for `fromJson()` in a matrix:
23+ # checks -- suites that run in the shared BCI container
24+ # docker_checks -- suites that need a live Docker daemon and so run directly
25+ # on the runner (STAC-25531)
3026#
31- # The split is a security boundary, not a convenience. The credential-free suites
32- # run with no secrets in scope at all. The private-index suites need a registry
33- # password, so they are kept in a separate job -- and, on pull requests, are not
34- # run at all (STAC-25540, second review pass).
35- #
36- # That last part is the whole point, so it is worth stating plainly: a
37- # `pull_request` run executes the pull request's own copy of the workflow and of
38- # every script it calls. Hardening the job cannot keep a determined pull request
39- # away from a secret the run is holding -- it can always edit the thing that holds
40- # it. The only run that cannot leak the credential is a run that never receives
41- # it, so these suites are deferred to push, tag and workflow_dispatch events,
42- # whose contents are reviewed before they reach the release branch.
27+ # Every suite here is credential-free, and that is worth keeping. Until
28+ # STAC-25544 `vsphere` resolved only against a private package registry, which
29+ # meant withholding the credential from pull requests and therefore not running
30+ # the suite on them at all -- a real coverage gap, because a `pull_request` run
31+ # executes the pull request's own copy of the workflow and of every script it
32+ # calls, so a run holding a secret cannot be hardened against the pull request
33+ # that edits it. Modernising the VMware pin onto public PyPI removed the secret
34+ # and with it the gap. If a suite ever appears to need a registry credential
35+ # again, removing that need is the fix; splitting the matrix is not.
4336
4437set -euo pipefail
4538
46- # Suites currently running on GitHub Actions. Phase 1 is the 15 suites that need
47- # no Docker daemon.
48- #
49- # Deliberately NOT here yet (phase 2, STAC-25531 -- needs a docker client in the
50- # job image):
51- # splunk_base, splunk_health, splunk_metric, splunk_topology
52- # -- each drives a real Splunk container via docker-compose.
53- # stackstate_checks_dev
54- # -- its tests exercise the toolkit's own Docker helpers.
55- # ubuntu-latest already provides a working Docker daemon, so this is a matter of
56- # giving the job a docker client rather than provisioning a runner.
39+ # Suites currently running on GitHub Actions.
5740#
5841# Deliberately dropped, not pending:
5942# postgres -- .gitlab-ci.yml carried a `test_postgres` job for a check that does
@@ -69,27 +52,45 @@ CHECKS=(
6952 kubelet
7053 openmetrics
7154 servicenow
55+ splunk_base
56+ splunk_health
57+ splunk_metric
58+ splunk_topology
7259 stackstate_checks_base
60+ stackstate_checks_dev
7361 static_health
7462 static_topology
7563 vsphere
7664 zabbix
7765)
7866
79- # Suites whose requirements resolve only against the private GitLab PyPI index.
80- # `vsphere` pins vsphere-automation-sdk, which VMware never published to public
81- # PyPI (the name is squatted there by an unrelated 0.0.1 placeholder), so it is
82- # mirrored into the StackVista package registry and needs authentication.
67+ # Suites that need a real Docker daemon: the four splunk suites drive a Splunk
68+ # container through docker-compose, and stackstate_checks_dev tests the toolkit's
69+ # own Docker helpers (STAC-25531).
8370#
84- # Everything not listed here is credential-free and must stay that way: adding a
85- # suite to this list stops it running on pull requests altogether, and removing
86- # the need for the private index is always the better fix. For vsphere that fix
87- # looks reachable -- VMware now publishes the SDK to public PyPI under renamed
88- # packages (vmware-vapi-runtime, vmware-vapi-common-client, pyvmomi) and ships
89- # the NSX/VMC wheels from its own public index -- so this list should shrink to
90- # nothing once the pin is modernised.
91- PRIVATE_INDEX_CHECKS=(
92- vsphere
71+ # These run as their own matrix directly on the runner, not inside the BCI
72+ # container the other suites use. That is not a preference -- the tests resolve
73+ # their target host through `get_docker_hostname()`, which reads DOCKER_HOST and
74+ # falls back to `localhost`. Compose publishes its ports on the Docker host, so
75+ # `localhost` is correct only when the test process shares a network namespace
76+ # with the daemon. Inside a job container it would resolve to the container
77+ # itself and every connection would be refused. GitLab avoided this by pointing
78+ # DOCKER_HOST at a `docker:dind` service, whose hostname then resolved for both.
79+ DOCKER_CHECKS=(
80+ splunk_base
81+ splunk_health
82+ splunk_metric
83+ splunk_topology
84+ stackstate_checks_dev
85+ )
86+
87+ # splunk_health, splunk_metric and splunk_topology all build on splunk_base, so a
88+ # change there has to run all four. Ported from the `splunk_base_build_rule`
89+ # anchor in .gitlab-ci.yml, which added the same fan-out to every splunk job.
90+ SPLUNK_DEPENDENTS=(
91+ splunk_health
92+ splunk_metric
93+ splunk_topology
9394)
9495
9596# A change anywhere here invalidates every suite: the base classes and the test
@@ -112,53 +113,37 @@ to_json() {
112113 fi
113114}
114115
115- is_private_index () {
116+ is_docker () {
116117 local candidate=$1 check
117- for check in " ${PRIVATE_INDEX_CHECKS [@]} " ; do
118+ for check in " ${DOCKER_CHECKS [@]} " ; do
118119 [ " ${candidate} " = " ${check} " ] && return 0
119120 done
120121 return 1
121122}
122123
123124emit () {
124125 local -a selected=(" $@ " )
125- local -a public=() private=() deferred =()
126+ local -a public=() docker =()
126127 local check
127128 for check in ${selected[@]+" ${selected[@]} " } ; do
128- if is_private_index " ${check} " ; then
129- private +=(" ${check} " )
129+ if is_docker " ${check} " ; then
130+ docker +=(" ${check} " )
130131 else
131132 public+=(" ${check} " )
132133 fi
133134 done
134135
135- # Pull requests do not run the private-index suites at all (STAC-25540, second
136- # review pass). See the security-boundary note at the top of this file: a
137- # `pull_request` run executes the pull request's own copy of the workflow and
138- # scripts, so the credential can only be protected by withholding it. These
139- # suites run on the release branch instead, where the code has been reviewed.
140- if [ " ${EVENT_NAME} " = " pull_request" ] && [ " ${# private[@]} " -gt 0 ]; then
141- deferred=(" ${private[@]} " )
142- private=()
143- fi
144-
145- local public_json private_json deferred_json
136+ local public_json docker_json
146137 public_json=$( to_json ${public[@]+" ${public[@]} " } )
147- private_json=$( to_json ${private[@]+" ${private[@]} " } )
148- deferred_json=$( to_json ${deferred[@]+" ${deferred[@]} " } )
138+ docker_json=$( to_json ${docker[@]+" ${docker[@]} " } )
149139
150140 {
151141 echo " checks=${public_json} "
152- echo " private_checks=${private_json} "
153- echo " deferred_private_checks=${deferred_json} "
142+ echo " docker_checks=${docker_json} "
154143 } >> " ${GITHUB_OUTPUT} "
155144
156145 echo " Selected credential-free suites: ${public_json} "
157- echo " Selected private-index suites: ${private_json} "
158- if [ " ${deferred_json} " != " []" ]; then
159- echo " Deferred private-index suites: ${deferred_json} "
160- echo " ::notice title=Private-index suites do not run on pull requests::${deferred_json} resolve only against the private package registry. Pull requests are deliberately given no credential to reach it, so these suites run on ${BASE_REF:- the release branch} after merge."
161- fi
146+ echo " Selected docker-daemon suites: ${docker_json} "
162147}
163148
164149# Anything that is not a pull request is a full run. On the release branch the
@@ -207,4 +192,15 @@ for file in "${CHANGED[@]}"; do
207192 done
208193done
209194
195+ # splunk_base is a library for the other three splunk suites, so pull them in
196+ # whenever it changes. Ported from `splunk_base_build_rule` in .gitlab-ci.yml.
197+ # `emit` sorts and de-duplicates, so adding them unconditionally is safe.
198+ for check in ${SELECTED[@]+" ${SELECTED[@]} " } ; do
199+ if [ " ${check} " = " splunk_base" ]; then
200+ echo " 'splunk_base' changed: also running ${SPLUNK_DEPENDENTS[*]} ."
201+ SELECTED+=(" ${SPLUNK_DEPENDENTS[@]} " )
202+ break
203+ fi
204+ done
205+
210206emit " ${SELECTED[@]+" ${SELECTED[@]} " } "
0 commit comments