-
Notifications
You must be signed in to change notification settings - Fork 0
126 lines (112 loc) · 4.27 KB
/
Copy pathdeploy.yml
File metadata and controls
126 lines (112 loc) · 4.27 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
name: Deploy Detections to Splunk
on:
push:
branches: [main]
paths:
- "detections/**/*.yml"
workflow_dispatch:
inputs:
deploy_all:
description: "Deploy all detection files instead of only files changed in the latest push"
required: false
type: boolean
default: false
deploy_status:
description: "Deployment status override used to enable or disable saved searches"
required: false
type: choice
default: production
options:
- draft
- testing
- production
- deprecated
permissions:
contents: read
pull-requests: read
concurrency:
group: splunk-deploy-main
cancel-in-progress: false
jobs:
deploy:
name: Deploy to Splunk
# Runs on the self-hosted Ubuntu runner (Orbstack) — needs local Splunk access
runs-on: [self-hosted, linux, dac]
env:
DEPLOY_STATUS: ${{ github.event_name == 'workflow_dispatch' && inputs.deploy_status || 'production' }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Verify deployment source
if: github.event_name == 'push'
shell: bash
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
merged_pr_count=$(curl -fsSL \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
"${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/commits/${GITHUB_SHA}/pulls" \
| jq '[.[] | select(.base.ref == "main" and .state == "closed" and .merged_at != null)] | length')
if [ "$merged_pr_count" -eq 0 ]; then
echo "::error::Deployments from main require a commit associated with a merged PR into main."
exit 1
fi
- name: Install dependencies
run: pip3 install --break-system-packages -r requirements.txt
- name: Show deployment status
run: echo "DEPLOY_STATUS=${DEPLOY_STATUS}"
- name: Identify changed detection files
id: changed
shell: bash
env:
BEFORE_SHA: ${{ github.event.before }}
DEPLOY_ALL: ${{ inputs.deploy_all || false }}
run: |
if [ "$DEPLOY_ALL" = "true" ]; then
CHANGED=$(find detections -type f -name '*.yml' | sort | tr '\n' ' ' | sed 's/[[:space:]]*$//')
DELETED=""
else
BASE="${BEFORE_SHA:-HEAD~1}"
if [[ "$BASE" =~ ^0+$ ]]; then
BASE="HEAD~1"
fi
CHANGED=$(git diff --name-only --diff-filter=ACMRT "$BASE" HEAD -- 'detections/**/*.yml' | tr '\n' ' ' | sed 's/[[:space:]]*$//')
DELETED=$(git diff --name-only --diff-filter=D "$BASE" HEAD -- 'detections/**/*.yml' | tr '\n' ' ' | sed 's/[[:space:]]*$//')
fi
echo "files=$CHANGED" >> "$GITHUB_OUTPUT"
echo "deleted=$DELETED" >> "$GITHUB_OUTPUT"
echo "Detections to deploy: $CHANGED"
if [ -n "$DELETED" ]; then
echo "Deleted detections detected: $DELETED"
fi
- name: Block deleted detection files
if: steps.changed.outputs.deleted != ''
run: |
echo "::error::Deleted detection files cannot be deployed safely. Use status: deprecated and an explicit Splunk decommission process."
echo "Deleted detections: ${{ steps.changed.outputs.deleted }}"
exit 1
- name: Dry-run deploy (preview)
if: steps.changed.outputs.files != ''
env:
SPLUNK_URL: ${{ secrets.SPLUNK_URL }}
SPLUNK_TOKEN: ${{ secrets.SPLUNK_TOKEN }}
SPLUNK_APP: ${{ vars.SPLUNK_APP || 'search' }}
run: |
python3 scripts/deploy.py \
--dry-run \
${{ steps.changed.outputs.files }}
- name: Deploy detections
if: steps.changed.outputs.files != ''
env:
SPLUNK_URL: ${{ secrets.SPLUNK_URL }}
SPLUNK_TOKEN: ${{ secrets.SPLUNK_TOKEN }}
SPLUNK_APP: ${{ vars.SPLUNK_APP || 'search' }}
run: |
python3 scripts/deploy.py \
${{ steps.changed.outputs.files }}
- name: No detections changed
if: steps.changed.outputs.files == ''
run: echo "No detection YAML files were modified — nothing to deploy."