forked from hyphanet/fred
-
Notifications
You must be signed in to change notification settings - Fork 0
237 lines (224 loc) · 10.3 KB
/
Copy pathrelease-certification.yml
File metadata and controls
237 lines (224 loc) · 10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
name: Release Certification
on:
workflow_dispatch:
inputs:
mode:
description: Certification mode.
required: true
default: nightly
type: choice
options:
- pr
- nightly
- release-candidate
extended-gates:
description: Run extended interop soak in addition to smoke/performance evidence.
required: true
default: false
type: boolean
previous-summary-path:
description: Optional local path to a candidate-bound migrate-v1 release-history v2 summary; candidate-release-id is required when set.
required: false
default: ''
type: string
require-history:
description: Fail release-candidate certification when no previous summary is available.
required: true
default: false
type: boolean
write-history:
description: Write sanitized current summaries under build/release-certification-history.
required: true
default: false
type: boolean
history-label:
description: Optional release or git-ref label for write-history output.
required: false
default: ''
type: string
waiver-file-path:
description: Optional local path to a structured release waiver JSON file.
required: false
default: ''
type: string
stable-readiness-summary-path:
description: Optional local path to a candidate-bound Stable readiness v2 summary; candidate-release-id is required when set.
required: false
default: ''
type: string
candidate-release-id:
description: Stable promotion candidate releaseId; required with previous-summary-path, any Stable readiness summary, or required Stable readiness.
required: false
default: ''
type: string
require-stable-readiness:
description: Fail certification when Stable 1.0 readiness is missing or failing.
required: true
default: false
type: boolean
schedule:
- cron: '47 5 * * *'
push:
branches: [ 'release/**' ]
tags: [ 'v*' ]
jobs:
certify:
runs-on: ubuntu-latest
timeout-minutes: 150
permissions:
contents: read
actions: write
env:
CERT_MODE: ${{ github.event_name == 'push' && 'release-candidate' || github.event.inputs.mode || 'nightly' }}
RUN_EXTENDED_GATES: ${{ github.event.inputs['extended-gates'] || 'false' }}
PREVIOUS_SUMMARY_PATH: ${{ github.event.inputs['previous-summary-path'] || '' }}
REQUIRE_HISTORY: ${{ github.event.inputs['require-history'] || 'false' }}
WRITE_HISTORY: ${{ github.event.inputs['write-history'] || 'false' }}
HISTORY_LABEL: ${{ github.event.inputs['history-label'] || '' }}
WAIVER_FILE_PATH: ${{ github.event.inputs['waiver-file-path'] || '' }}
STABLE_READINESS_SUMMARY_PATH: ${{ github.event.inputs['stable-readiness-summary-path'] || '' }}
CANDIDATE_RELEASE_ID: ${{ github.event.inputs['candidate-release-id'] || '' }}
REQUIRE_STABLE_READINESS: ${{ github.event.inputs['require-stable-readiness'] || 'false' }}
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Set up JDK 25
uses: actions/setup-java@v5
with:
java-version: '25'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5
- name: Install Gradle properties
uses: ./.github/actions/setup-gradle-properties
- name: Run release certification self-tests
run: python3 tools/release-certification/certify.py self-test all
- name: Run Hyphanet interop smoke
continue-on-error: true
env:
GITHUB_TOKEN: ${{ github.token }}
INTEROP_MODE: smoke
run: tools/interop/run-hyphanet-interop-smoke.sh
- name: Run extended Hyphanet interop
if: env.RUN_EXTENDED_GATES == 'true'
continue-on-error: true
env:
INTEROP_MODE: extended
INTEROP_ENABLE_USK_SUBSCRIBE_SOAK: '1'
INTEROP_ENABLE_PERSISTENT_REPLAY: '1'
INTEROP_ENABLE_OPENNET: '0'
INTEROP_SOAK_DURATION_SECONDS: '900'
INTEROP_SOAK_POLL_INTERVAL_SECONDS: '15'
INTEROP_EXTENDED_TIMEOUT_SECONDS: '3600'
INTEROP_OUT_DIR: build/interop-extended
INTEROP_TIMEOUT_SECONDS: '3600'
INTEROP_SKIP_BUILD: '1'
run: tools/interop/run-hyphanet-interop-smoke.sh
- name: Run performance smoke
continue-on-error: true
env:
PERF_MODE: smoke
PERF_OUT_DIR: build/perf-smoke
PERF_TIMEOUT_SECONDS: '900'
PERF_SKIP_BUILD: '1'
run: tools/perf/run-performance-smoke.sh
- name: Generate release certification report
env:
CRYPTAD_CERT_MODE: ${{ env.CERT_MODE }}
CRYPTAD_APP_SIGNING_KEY_ID: ${{ secrets.CRYPTAD_APP_SIGNING_KEY_ID }}
CRYPTAD_APP_SIGNING_PRIVATE_KEY_BASE64: ${{ secrets.CRYPTAD_APP_SIGNING_PRIVATE_KEY_BASE64 }}
CRYPTAD_APP_SIGNING_PUBLIC_KEY_BASE64: ${{ secrets.CRYPTAD_APP_SIGNING_PUBLIC_KEY_BASE64 }}
CRYPTAD_APP_SIGNING_PRIVATE_KEY_FILE: ${{ secrets.CRYPTAD_APP_SIGNING_PRIVATE_KEY_FILE }}
CRYPTAD_APP_SIGNING_PUBLIC_KEY_FILE: ${{ secrets.CRYPTAD_APP_SIGNING_PUBLIC_KEY_FILE }}
CRYPTAD_APP_REVIEWER_KEY_ID: ${{ secrets.CRYPTAD_APP_REVIEWER_KEY_ID }}
CRYPTAD_APP_REVIEWER_PRIVATE_KEY_BASE64: ${{ secrets.CRYPTAD_APP_REVIEWER_PRIVATE_KEY_BASE64 }}
CRYPTAD_APP_REVIEWER_PUBLIC_KEY_BASE64: ${{ secrets.CRYPTAD_APP_REVIEWER_PUBLIC_KEY_BASE64 }}
CRYPTAD_APP_REVIEWER_PRIVATE_KEY_FILE: ${{ secrets.CRYPTAD_APP_REVIEWER_PRIVATE_KEY_FILE }}
CRYPTAD_APP_REVIEWER_PUBLIC_KEY_FILE: ${{ secrets.CRYPTAD_APP_REVIEWER_PUBLIC_KEY_FILE }}
CRYPTAD_APP_REVIEW_POLICY_ID: ${{ secrets.CRYPTAD_APP_REVIEW_POLICY_ID }}
CRYPTAD_APP_REVIEW_POLICY_VERSION: ${{ secrets.CRYPTAD_APP_REVIEW_POLICY_VERSION }}
run: |
if [[ "$REQUIRE_STABLE_READINESS" == "true" && -z "$CANDIDATE_RELEASE_ID" ]]; then
echo "candidate-release-id is required when require-stable-readiness is true." >&2
exit 2
fi
if [[ -n "$STABLE_READINESS_SUMMARY_PATH" && -z "$CANDIDATE_RELEASE_ID" ]]; then
echo "candidate-release-id is required when stable-readiness-summary-path is supplied." >&2
exit 2
fi
if [[ -n "$PREVIOUS_SUMMARY_PATH" && -z "$CANDIDATE_RELEASE_ID" ]]; then
echo "candidate-release-id is required when previous-summary-path is supplied." >&2
exit 2
fi
release_id="${CANDIDATE_RELEASE_ID:-ci-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}}"
release_version="$(./gradlew -q printVersion)"
if [[ ! "$release_version" =~ ^[0-9]+$ ]]; then
echo "::error::Expected a numeric project version from ./gradlew -q printVersion, got '$release_version'."
exit 2
fi
interop_smoke=""
interop_extended=""
performance_smoke=""
if [[ -f "build/interop-smoke/summary.json" ]]; then
interop_smoke="build/interop-smoke/summary.json"
fi
if [[ -f "build/interop-extended/summary.json" ]]; then
interop_extended="build/interop-extended/summary.json"
fi
if [[ -f "build/perf-smoke/summary.json" ]]; then
performance_smoke="build/perf-smoke/summary.json"
fi
manifest="$RUNNER_TEMP/release-certification-manifest.json"
jq -n \
--arg release_id "$release_id" \
--arg release_version "$release_version" \
--arg profile "$CERT_MODE" \
--arg interop_smoke "$interop_smoke" \
--arg interop_extended "$interop_extended" \
--arg performance_smoke "$performance_smoke" \
--arg release_history "$PREVIOUS_SUMMARY_PATH" \
--arg waiver_file "$WAIVER_FILE_PATH" \
--arg stable_readiness "$STABLE_READINESS_SUMMARY_PATH" \
--arg history_label "$HISTORY_LABEL" \
--argjson require_history "$REQUIRE_HISTORY" \
--argjson write_history "$WRITE_HISTORY" \
--argjson require_stable "$REQUIRE_STABLE_READINESS" \
'{
schemaVersion: 1,
release: {id: $release_id, version: $release_version, profile: $profile},
output: {root: "build/release-certification", reset: true},
requirements: {
history: $require_history,
liveNetwork: false,
multiNodeSoak: true,
sandboxProviderTests: true,
stableReadiness: $require_stable,
thirdPartyIntake: true
},
inputs: ({}
+ (if $interop_smoke == "" then {} else {interopSmoke: $interop_smoke} end)
+ (if $interop_extended == "" then {} else {interopExtended: $interop_extended} end)
+ (if $performance_smoke == "" then {} else {performanceSmoke: $performance_smoke} end)
+ (if $release_history == "" then {} else {releaseHistory: $release_history} end)
+ (if $waiver_file == "" then {} else {waiverFile: $waiver_file} end)
+ (if $stable_readiness == "" then {} else {stableReadiness: $stable_readiness} end)),
policies: ({metadata: {candidateReleaseId: $release_id}}
+ (if $history_label == "" then {} else {historyLabel: $history_label} end)),
execution: {collectEvidence: true, writeHistory: $write_history},
commands: {}
}' > "$manifest"
python3 tools/release-certification/certify.py release-certification --manifest "$manifest"
- name: Upload release certification artifacts
if: always()
uses: actions/upload-artifact@v6
with:
name: release-certification-${{ github.run_id }}-${{ github.run_attempt }}
path: |
build/release-certification/
build/release-certification-history/
!**/private-insert-uris.json
if-no-files-found: warn
retention-days: 30