Skip to content

Commit 1da280a

Browse files
committed
add automated public repo validation gates
1 parent 88952d8 commit 1da280a

5 files changed

Lines changed: 174 additions & 2 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: public repo gates
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
repo-gates:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Check out repository
16+
uses: actions/checkout@v4
17+
18+
- name: Install validation dependencies
19+
run: |
20+
sudo apt-get update
21+
sudo apt-get install -y ksh
22+
23+
- name: Run repo-only validation gates
24+
run: |
25+
ksh ./scripts/verify/run-repo-ci-gates.ksh

‎CONTRIBUTING.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,16 @@ Examples:
100100
- dry-run execution for installer and phase tooling
101101
- QEMU or lab validation for install, verify, and upgrade paths
102102
- documentation walkthrough validation for onboarding changes
103+
- the GitHub Actions repo-only validation workflow for changes that affect public automation or validation behavior
103104

104105
If something cannot be tested locally, say so clearly in the pull request.
105106

107+
To mirror the current public CI gate locally, run:
108+
109+
```sh
110+
./scripts/verify/run-repo-ci-gates.ksh
111+
```
112+
106113
## Pull Request Guidance
107114

108115
A good pull request should include:

‎README.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,22 @@ Useful commands after the repository is populated with local inputs. The install
134134
./scripts/install/run-phase-sequence.ksh --phase-start 0 --phase-end 10
135135
./scripts/verify/run-post-install-checks.ksh
136136
./maint/validate-public-hardening-surface.ksh
137+
./scripts/verify/run-repo-ci-gates.ksh
137138
```
138139

140+
141+
## Automated public repo gates
142+
143+
The repository now includes a GitHub Actions workflow that runs repo-only validation on push and pull request for `main`.
144+
145+
The local helper used by that workflow is:
146+
147+
```sh
148+
./scripts/verify/run-repo-ci-gates.ksh
149+
```
150+
151+
It renders live test output into temporary gitignored paths, validates the repo semantic checks, and exercises the public-safe render and phase surfaces that can be proven without a live OpenBSD host.
152+
139153
## Repository companions
140154

141155
- `SECURITY.md` for reporting security issues

‎docs/install/19-public-repo-readiness-check.md‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,25 @@ The current repo-side semantic verifier is:
6262
./scripts/verify/verify-repo-semantic-integrity.ksh
6363
```
6464

65-
## E. Intentional boundaries
65+
66+
## E. Automated public repo gates
67+
68+
The repository now includes a public CI workflow for repo-only validation. That workflow should be able to run without private inputs or a live OpenBSD host.
69+
70+
The local mirror of that workflow is:
71+
72+
```sh
73+
./scripts/verify/run-repo-ci-gates.ksh
74+
```
75+
76+
It should be able to:
77+
78+
- create temporary example-backed operator inputs
79+
- render live runtime trees into temporary gitignored paths
80+
- run repo semantic integrity checks
81+
- exercise the public-safe render and phase surfaces that are valid to prove in CI
82+
83+
## F. Intentional boundaries
6684

6785
The following are still intentionally private:
6886

@@ -71,7 +89,7 @@ The following are still intentionally private:
7189
- real secrets, PATs, API tokens, and private keys
7290
- site-specific control-plane doctrine
7391

74-
## F. Final operator reality
92+
## G. Final operator reality
7593

7694
The public repository is considered ready when the remaining work is local operator population of:
7795

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/bin/ksh
2+
set -eu
3+
( set -o pipefail ) 2>/dev/null && set -o pipefail
4+
5+
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)"
6+
PROJECT_ROOT="$(CDPATH= cd -- "${SCRIPT_DIR}/../.." && pwd -P)"
7+
COMMON_LIB="${PROJECT_ROOT}/scripts/lib/common.ksh"
8+
9+
[ -f "${COMMON_LIB}" ] || {
10+
print -- "ERROR missing shared library: ${COMMON_LIB}" >&2
11+
exit 1
12+
}
13+
14+
. "${COMMON_LIB}"
15+
16+
TMP_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/openbsd-mailstack-ci.XXXXXX")"
17+
INPUT_ROOT="${TMP_ROOT}/inputs"
18+
CI_HOME="${TMP_ROOT}/home"
19+
20+
cleanup() {
21+
rm -rf "${TMP_ROOT}"
22+
}
23+
trap cleanup EXIT INT TERM HUP
24+
25+
run() {
26+
log_info "running: $*"
27+
"$@"
28+
}
29+
30+
copy_example_configs() {
31+
ensure_directory "${INPUT_ROOT}"
32+
for _src in "${PROJECT_ROOT}"/config/*.example; do
33+
[ -f "${_src}" ] || continue
34+
_base="$(basename -- "${_src}" .example)"
35+
cp -f "${_src}" "${INPUT_ROOT}/${_base}" || die "failed copying example config ${_src}"
36+
done
37+
}
38+
39+
write_ci_overrides() {
40+
cat >> "${INPUT_ROOT}/secrets.conf" <<'EOF2'
41+
VULTR_API_KEY="ci-vultr-api-key"
42+
BREVO_API_KEY="ci-brevo-api-key"
43+
BREVO_SMTP_KEY="ci-brevo-smtp-key"
44+
VIRUSTOTAL_API_KEY="ci-virustotal-api-key"
45+
BREVO_SMTP_LOGIN="ci-brevo-login"
46+
BREVO_SMTP_PASSWORD="ci-brevo-password"
47+
POSTFIXADMIN_SETUP_PASSWORD_HASH="ci-postfixadmin-setup-hash"
48+
RSPAMD_CONTROLLER_PASSWORD_HASH="ci-rspamd-password-hash"
49+
EOF2
50+
}
51+
52+
prepare_ci_environment() {
53+
copy_example_configs
54+
write_ci_overrides
55+
ensure_directory "${CI_HOME}"
56+
57+
export HOME="${CI_HOME}"
58+
export OPENBSD_MAILSTACK_NONINTERACTIVE=1
59+
export OPENBSD_MAILSTACK_INPUT_ROOT="${INPUT_ROOT}"
60+
export OPENBSD_MAILSTACK_EXTRA_INPUT_FILES=""
61+
export OPENBSD_MAILSTACK_CORE_RENDER_ROOT="${TMP_ROOT}/runtime/rootfs"
62+
export OPENBSD_MAILSTACK_NETWORK_RENDER_ROOT="${TMP_ROOT}/network/rootfs"
63+
export OPENBSD_MAILSTACK_IDENTITY_RENDER_ROOT="${TMP_ROOT}/identity"
64+
export OPENBSD_MAILSTACK_ADVANCED_RENDER_ROOT="${TMP_ROOT}/advanced/rootfs"
65+
export OPENBSD_MAILSTACK_ADVANCED_SBOM_ROOT="${TMP_ROOT}/advanced/sbom"
66+
export OPENBSD_MAILSTACK_BACKUP_DR_WORK_ROOT="${TMP_ROOT}/backup-dr"
67+
}
68+
69+
main() {
70+
prepare_ci_environment
71+
72+
run "${PROJECT_ROOT}/scripts/verify/verify-repo-semantic-integrity.ksh"
73+
run "${PROJECT_ROOT}/scripts/verify/verify-public-repo-readiness.ksh"
74+
75+
run "${PROJECT_ROOT}/scripts/install/render-core-runtime-configs.ksh"
76+
run "${PROJECT_ROOT}/scripts/verify/verify-core-runtime-assets.ksh"
77+
78+
run "${PROJECT_ROOT}/scripts/phases/phase-02-verify.ksh"
79+
run "${PROJECT_ROOT}/scripts/phases/phase-03-verify.ksh"
80+
run "${PROJECT_ROOT}/scripts/phases/phase-04-verify.ksh"
81+
run "${PROJECT_ROOT}/scripts/phases/phase-05-verify.ksh"
82+
run "${PROJECT_ROOT}/scripts/phases/phase-06-verify.ksh"
83+
run "${PROJECT_ROOT}/scripts/phases/phase-07-verify.ksh"
84+
run "${PROJECT_ROOT}/scripts/phases/phase-08-verify.ksh"
85+
86+
run "${PROJECT_ROOT}/scripts/install/render-network-exposure-configs.ksh"
87+
run "${PROJECT_ROOT}/scripts/verify/verify-network-exposure-assets.ksh"
88+
run "${PROJECT_ROOT}/scripts/phases/phase-09-apply.ksh"
89+
run "${PROJECT_ROOT}/scripts/phases/phase-09-verify.ksh"
90+
91+
run "${PROJECT_ROOT}/scripts/install/render-advanced-gap-configs.ksh"
92+
run "${PROJECT_ROOT}/scripts/verify/verify-advanced-gap-assets.ksh"
93+
94+
run "${PROJECT_ROOT}/scripts/phases/phase-11-apply.ksh"
95+
run "${PROJECT_ROOT}/scripts/phases/phase-11-verify.ksh"
96+
run "${PROJECT_ROOT}/scripts/phases/phase-12-apply.ksh"
97+
run "${PROJECT_ROOT}/scripts/phases/phase-12-verify.ksh"
98+
run "${PROJECT_ROOT}/scripts/phases/phase-13-apply.ksh"
99+
run "${PROJECT_ROOT}/scripts/phases/phase-13-verify.ksh"
100+
run "${PROJECT_ROOT}/scripts/ops/backup-dr-readiness-report.ksh" --write
101+
run "${PROJECT_ROOT}/scripts/verify/verify-backup-dr-assets.ksh"
102+
103+
run "${PROJECT_ROOT}/maint/validate-public-hardening-surface.ksh"
104+
105+
log_info "repo-only CI gates completed successfully"
106+
}
107+
108+
main "$@"

0 commit comments

Comments
 (0)