-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.gitlab-ci.yml
More file actions
325 lines (296 loc) · 10.8 KB
/
.gitlab-ci.yml
File metadata and controls
325 lines (296 loc) · 10.8 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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# =============================================================================
# AirGap DevKit — GitLab CI/CD Pipeline
# See ci/gitlab/SETUP.md for setup instructions and variable reference.
#
# Override any variable below via:
# CI/CD > Pipelines > Run pipeline > Add variables
# or via GitLab CI/CD Settings > Variables for persistent defaults.
# =============================================================================
# ── Default variables (all overridable per-run) ───────────────────────────────
variables:
# Identity
TEAM_NAME: "My Team"
ORG_NAME: ""
DEVKIT_NAME: "AirGap DevKit"
# Install
PROFILE: "minimal" # minimal | cpp-dev | devops | full
TARGET_OS: "linux" # linux | windows | both
SERVER_HOST: "127.0.0.1"
SERVER_PORT: "9090"
ADMIN_INSTALL: "false"
# Package upload — set UPLOAD_PACKAGE=true and PACKAGE_FILE_PATH to activate
UPLOAD_PACKAGE: "false"
PACKAGE_FILE_PATH: "" # absolute path on the runner to a .zip file
# Team config
EXPORT_TEAM_CONFIG: "false"
IMPORT_TEAM_CONFIG: "" # raw JSON body for POST /api/import
# Custom profile — set to JSON body for POST /api/profiles to activate
SAVE_PROFILE_JSON: ""
# Tests
RUN_VALIDATE: "true"
RUN_SMOKE_TESTS: "true"
# Atlassian — set ATLASSIAN_UPDATE=true and supply issue/page IDs to activate
ATLASSIAN_UPDATE: "false"
JIRA_ISSUE_KEY: "" # e.g. DEVKIT-42
CONFLUENCE_PAGE_ID: "" # numeric page ID
# Internal
GIT_SUBMODULE_STRATEGY: recursive
# ── Stages ────────────────────────────────────────────────────────────────────
stages:
- validate
- configure
- install
- server-ops
- test
- atlassian
# ── Workflow rules — run on default branch pushes, MRs, and manual triggers ──
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "web"
- if: $CI_PIPELINE_SOURCE == "schedule"
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# ── Shared config applied to every job ───────────────────────────────────────
default:
interruptible: true
# =============================================================================
# VALIDATE
# =============================================================================
validate:manifests:
stage: validate
tags: [linux]
rules:
- if: $RUN_VALIDATE == "true"
- when: never
script:
- bash tests/validate-manifests.sh --verbose
# =============================================================================
# CONFIGURE
# Patches devkit.config.json with pipeline variables and saves it as an
# artifact so downstream jobs pick up the same values.
# =============================================================================
configure:
stage: configure
tags: [linux]
script:
- |
python3 - <<'PYEOF'
import json, os
with open("devkit.config.json") as f:
cfg = json.load(f)
team = os.environ.get("TEAM_NAME", "").strip()
org = os.environ.get("ORG_NAME", "").strip()
dk = os.environ.get("DEVKIT_NAME", "").strip()
host = os.environ.get("SERVER_HOST", "127.0.0.1").strip()
port = int(os.environ.get("SERVER_PORT", "9090"))
prof = os.environ.get("PROFILE", "minimal").strip()
if team: cfg["team_name"] = team
if org is not None: cfg["org_name"] = org
if dk: cfg["devkit_name"] = dk
cfg["hostname"] = host
cfg["port"] = port
cfg["default_profile"] = prof
with open("devkit.config.json", "w") as f:
json.dump(cfg, f, indent=2)
print(f"Configured: team={cfg['team_name']}, profile={cfg['default_profile']}, port={cfg['port']}")
PYEOF
artifacts:
paths:
- devkit.config.json
expire_in: 1 hour
# =============================================================================
# INSTALL
# =============================================================================
install:linux:
stage: install
tags: [linux]
needs: [configure]
rules:
- if: $TARGET_OS == "linux" || $TARGET_OS == "both"
- when: never
script:
- |
FLAGS="--yes --profile ${PROFILE}"
[ "${ADMIN_INSTALL}" = "true" ] && FLAGS="${FLAGS} --admin"
bash scripts/internal/install-cli.sh ${FLAGS}
artifacts:
paths:
- "**/INSTALL_RECEIPT.txt"
expire_in: 7 days
when: always
install:windows:
stage: install
tags: [windows]
needs: [configure]
rules:
- if: $TARGET_OS == "windows" || $TARGET_OS == "both"
- when: never
script:
- bash scripts/internal/install-cli.sh --yes --profile "${PROFILE}"
artifacts:
paths:
- "**/INSTALL_RECEIPT.txt"
expire_in: 7 days
when: always
# =============================================================================
# SERVER OPERATIONS
# Start the devkit server, exercise the API (config push, optional package
# upload / profile save / team import / export), collect health snapshot,
# then cleanly stop the server.
# =============================================================================
server-ops:
stage: server-ops
tags: [linux]
needs: [configure]
script:
# Start server
- nohup bash scripts/launch.sh --no-browser > devkit-server.log 2>&1 &
- echo $! > .server.pid
- echo "Server PID $(cat .server.pid)"
- |
echo "Waiting for http://${SERVER_HOST}:${SERVER_PORT}/health ..."
for i in $(seq 1 30); do
if curl -sf "http://${SERVER_HOST}:${SERVER_PORT}/health" >/dev/null 2>&1; then
echo "Server ready (attempt ${i})"
break
fi
sleep 2
if [ "${i}" -eq 30 ]; then
echo "ERROR: server did not start within 60s"
cat devkit-server.log
exit 1
fi
done
# Read auth token written by the server on first start
- DEVKIT_TOKEN=$(cat .devkit-token 2>/dev/null || echo "")
# Push team identity
- |
printf '{"team_name":"%s","org_name":"%s","devkit_name":"%s"}' \
"${TEAM_NAME}" "${ORG_NAME}" "${DEVKIT_NAME}" > /tmp/dk-config.json
curl -sf -X POST \
-H 'Content-Type: application/json' \
-H "X-DevKit-Token: ${DEVKIT_TOKEN}" \
-d @/tmp/dk-config.json \
"http://${SERVER_HOST}:${SERVER_PORT}/api/config"
echo "Team identity pushed"
# Upload package bundle (optional)
- |
if [ "${UPLOAD_PACKAGE}" = "true" ]; then
if [ -z "${PACKAGE_FILE_PATH}" ]; then
echo "ERROR: UPLOAD_PACKAGE=true but PACKAGE_FILE_PATH is empty"; exit 1
fi
if [ ! -f "${PACKAGE_FILE_PATH}" ]; then
echo "ERROR: '${PACKAGE_FILE_PATH}' not found on runner"; exit 1
fi
curl -sf -X POST \
-H "X-DevKit-Token: ${DEVKIT_TOKEN}" \
-F "package=@${PACKAGE_FILE_PATH}" \
"http://${SERVER_HOST}:${SERVER_PORT}/packages/upload"
echo "Package uploaded: ${PACKAGE_FILE_PATH}"
fi
# Save custom profile (optional)
- |
if [ -n "${SAVE_PROFILE_JSON}" ]; then
echo "${SAVE_PROFILE_JSON}" | \
curl -sf -X POST \
-H 'Content-Type: application/json' \
-H "X-DevKit-Token: ${DEVKIT_TOKEN}" \
-d @- \
"http://${SERVER_HOST}:${SERVER_PORT}/api/profiles"
echo "Custom profile saved"
fi
# Import team config (optional)
- |
if [ -n "${IMPORT_TEAM_CONFIG}" ]; then
echo "${IMPORT_TEAM_CONFIG}" | \
curl -sf -X POST \
-H 'Content-Type: application/json' \
-H "X-DevKit-Token: ${DEVKIT_TOKEN}" \
-d @- \
"http://${SERVER_HOST}:${SERVER_PORT}/api/import"
echo "Team config imported"
fi
# Export team config (optional)
- |
if [ "${EXPORT_TEAM_CONFIG}" = "true" ]; then
curl -sf \
-H "X-DevKit-Token: ${DEVKIT_TOKEN}" \
"http://${SERVER_HOST}:${SERVER_PORT}/api/export" \
-o team-config-export.json
echo "Team config exported"
fi
# Tool health snapshot (always)
- |
curl -sf \
-H "X-DevKit-Token: ${DEVKIT_TOKEN}" \
"http://${SERVER_HOST}:${SERVER_PORT}/api/health/tools" \
-o tool-health.json
echo "Tool health:"
cat tool-health.json
# Stop server
- kill "$(cat .server.pid 2>/dev/null)" 2>/dev/null || true
after_script:
- kill "$(cat .server.pid 2>/dev/null)" 2>/dev/null || true
- rm -f .server.pid /tmp/dk-config.json /tmp/dk-profile.json /tmp/dk-import.json
artifacts:
paths:
- devkit-server.log
- tool-health.json
- team-config-export.json
expire_in: 14 days
when: always
# =============================================================================
# SMOKE TESTS
# =============================================================================
test:linux:
stage: test
tags: [linux]
rules:
- if: $RUN_SMOKE_TESTS == "true" && ($TARGET_OS == "linux" || $TARGET_OS == "both")
- when: never
script:
- bash tests/run-tests.sh --verbose
- bash tests/check-installed-tools.sh --verbose
allow_failure: false
test:windows:
stage: test
tags: [windows]
rules:
- if: $RUN_SMOKE_TESTS == "true" && ($TARGET_OS == "windows" || $TARGET_OS == "both")
- when: never
script:
- bash tests/run-tests.sh --verbose
allow_failure: false
# =============================================================================
# ATLASSIAN
# Update Jira issue and/or Confluence page with build results.
# Requires CI/CD secret variables: ATLASSIAN_BASE_URL, ATLASSIAN_USER_EMAIL,
# ATLASSIAN_API_TOKEN (set as masked variables in GitLab CI/CD Settings).
# =============================================================================
atlassian:update:
stage: atlassian
tags: [linux]
rules:
- if: $ATLASSIAN_UPDATE == "true" && ($JIRA_ISSUE_KEY != "" || $CONFLUENCE_PAGE_ID != "")
- when: never
script:
- |
BUILD_STATUS="${CI_JOB_STATUS:-UNKNOWN}"
BUILD_URL="${CI_PIPELINE_URL}"
if [ -n "${JIRA_ISSUE_KEY}" ]; then
bash ci/atlassian/jira-update.sh \
--issue "${JIRA_ISSUE_KEY}" \
--status "${BUILD_STATUS}" \
--url "${BUILD_URL}" \
--profile "${PROFILE}" \
--team "${TEAM_NAME}"
fi
if [ -n "${CONFLUENCE_PAGE_ID}" ]; then
bash ci/atlassian/confluence-update.sh \
--page-id "${CONFLUENCE_PAGE_ID}" \
--status "${BUILD_STATUS}" \
--url "${BUILD_URL}" \
--profile "${PROFILE}" \
--team "${TEAM_NAME}" \
--build "${CI_PIPELINE_IID}"
fi