-
-
Notifications
You must be signed in to change notification settings - Fork 0
166 lines (151 loc) · 6.95 KB
/
Copy pathappinspect.yml
File metadata and controls
166 lines (151 loc) · 6.95 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
name: AppInspect
# Phase 1.2 deliverable (added 2026-05-17, Phase 1 work).
#
# Runs Splunk's static AppInspect against the .spl built by
# scripts/package.sh, against both target profiles:
# - splunk-platform-standalone (on-prem Splunk Enterprise)
# - cloud (Splunk Cloud Vetting — static stage only)
#
# The acceptance gate per PUBLIC_RELEASE_PLAN.md Phase 1.2 is:
# zero errors AND zero failures AND zero future_failures on both
# profiles. Warnings are allowed and triaged per docs/APPINSPECT_FINDINGS.md.
#
# Implementation note: the Phase 1.2 task in PUBLIC_RELEASE_PLAN.md
# named `splunk/appinspect-cli-action` as the suggested wiring. That
# action is a thin wrapper around `pip install splunk-appinspect` +
# `splunk-appinspect inspect ...` (the same call our local Docker
# image runs). Using the underlying CLI directly avoids being pinned
# to a specific action version + lets the workflow stay aligned with
# the local re-run command documented in docs/APPINSPECT_FINDINGS.md
# §6 byte-for-byte. To swap in the official action wrapper later,
# replace the "Run AppInspect" steps below with a `splunk/appinspect-cli-action@<ver>` step.
#
# Python pin: Python 3.11 is required because splunk-appinspect 4.2.0's
# transitive deps (pillow, lxml) lack pre-built wheels for 3.14+ and
# source-build fails in pip's dep resolver. This is the exact pin called
# out in `.planning/go-public/PHASE_0_0_APPINSPECT_FINDINGS.md` §2.
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
permissions:
contents: read
# Cancel in-flight runs on the same ref when a new commit lands.
# AppInspect against the whole .spl takes ~1-2 minutes per profile;
# coalescing prevents queue pileup on rapid pushes.
concurrency:
group: appinspect-${{ github.ref }}
cancel-in-progress: true
jobs:
appinspect:
name: AppInspect (CLI)
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
# `cache: pip` was removed 2026-05-18 — actions/setup-python@v5
# requires `requirements.txt` or `pyproject.toml` to compute the
# cache key, and this repo has neither (only requirements-dev.txt,
# not a name setup-python globs for). The single `pip install` in
# this job uses `--no-cache-dir` anyway so caching was a no-op.
# Specifying `cache-dependency-path: requirements-dev.txt` would
# restore the cache, but with a single one-line install of a pinned
# package the cache hit is worthless. Keep simple.
- name: Set up Python 3.11
uses: actions/setup-python@v6
with:
python-version: '3.11'
# libmagic1 is required by splunk-appinspect's `python-magic`
# transitive dep. Without it the install succeeds but every
# MIME-type check in AppInspect raises.
- name: Install libmagic
run: sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libmagic1
- name: Install splunk-appinspect
# Pinned to 4.2.0 (the version validated in Phase 0.0 +
# Phase 1.3 baselines). Unpinned `pip install splunk-appinspect`
# would pull the newest 4.x at workflow-run time, which can
# introduce new checks Splunk adds in a point release and
# cause the gate to flip red on a Splunk-side change rather
# than a wl_manager-side change. When bumping this pin,
# re-run the Phase 1.3 baseline locally first and update
# `.planning/appinspect/appinspect-*-phase1.json` + the
# APPINSPECT_FINDINGS.md headline-numbers table in the
# same commit.
run: pip install --no-cache-dir splunk-appinspect==4.2.0
- name: Build .spl
run: bash scripts/package.sh
# Locate the built artifact. scripts/package.sh derives the
# filename from default/app.conf:[launcher] version, so we
# don't hardcode it here — keeps the workflow alive across RC
# bumps without an edit.
- name: Locate .spl
id: spl
run: |
set -euo pipefail
SPL_FILE="$(ls -1 dist/wl_manager-*.spl | head -1)"
if [[ -z "$SPL_FILE" ]]; then
echo "ERROR: no .spl produced under dist/"
exit 1
fi
echo "spl_file=$SPL_FILE" >> "$GITHUB_OUTPUT"
echo "Built: $SPL_FILE ($(du -h "$SPL_FILE" | cut -f1))"
- name: Run AppInspect — splunk-platform-standalone profile
run: |
mkdir -p .planning/appinspect
splunk-appinspect inspect "${{ steps.spl.outputs.spl_file }}" \
--mode test \
--data-format json \
--output-file .planning/appinspect/appinspect-standalone-ci.json
# Surface the summary in the run log for at-a-glance review.
splunk-appinspect inspect "${{ steps.spl.outputs.spl_file }}" \
--mode test \
--data-format human 2>&1 | tail -20 || true
- name: Run AppInspect — cloud profile
run: |
splunk-appinspect inspect "${{ steps.spl.outputs.spl_file }}" \
--mode test \
--data-format json \
--included-tags cloud \
--output-file .planning/appinspect/appinspect-cloud-ci.json
splunk-appinspect inspect "${{ steps.spl.outputs.spl_file }}" \
--mode test \
--data-format human \
--included-tags cloud 2>&1 | tail -20 || true
# Hard gate: any error / failure / future_failure on either
# profile fails the workflow. Warnings are allowed (per
# docs/APPINSPECT_FINDINGS.md triage). Uses Python rather than
# jq so we don't have to install extra packages.
- name: Enforce gate (0 errors / 0 failures / 0 future_failures)
run: |
python3 - <<'PY'
import json, sys
fatal = 0
for profile, path in [
("standalone", ".planning/appinspect/appinspect-standalone-ci.json"),
("cloud", ".planning/appinspect/appinspect-cloud-ci.json"),
]:
with open(path) as f:
data = json.load(f)
summary = data["summary"]
err = summary.get("error", 0)
fail = summary.get("failure", 0)
fut = summary.get("future_failure", 0)
warn = summary.get("warning", 0)
succ = summary.get("success", 0)
print(f"[{profile}] error={err} failure={fail} future_failure={fut} warning={warn} success={succ}")
if err or fail or fut:
fatal += err + fail + fut
if fatal:
print(f"\nGATE FAILED: {fatal} blocker(s) across both profiles. See artifact JSON for details.")
sys.exit(1)
print("\nGATE PASSED: 0 errors / 0 failures / 0 future_failures on both profiles.")
PY
- name: Upload AppInspect JSON reports
if: always()
uses: actions/upload-artifact@v7
with:
name: appinspect-reports
path: .planning/appinspect/appinspect-*-ci.json
retention-days: 30