@@ -2,73 +2,55 @@ name: CI/CD Pipeline
22
33on :
44 pull_request :
5- branches :
6- - master
5+ branches : [ master ]
76 push :
8- branches :
9- - master
7+ branches : [ master ]
8+
109
1110jobs :
1211 lint :
1312 name : Linting & Code Quality
1413 runs-on : ubuntu-latest
15-
1614 steps :
1715 - name : Checkout code
1816 uses : actions/checkout@v4
19-
2017 - name : Set up Python
2118 uses : actions/setup-python@v5
2219 with :
2320 python-version : ' 3.11'
24-
2521 - name : Install dependencies
2622 run : |
2723 python -m pip install --upgrade pip
2824 pip install ruff black mypy
2925 pip install -e ".[dev]"
30-
3126 - name : Run Ruff
3227 run : ruff check src/ tests/ examples/
33-
3428 - name : Run Black
3529 run : black --check src/ tests/ examples/
36-
3730 - name : Run MyPy
3831 run : mypy src/
3932 continue-on-error : true
4033
4134 test :
4235 name : Unit Tests
4336 runs-on : ubuntu-latest
44- strategy :
45- matrix :
46- python-version : ['3.8', '3.9', '3.10', '3.11']
47-
4837 steps :
4938 - name : Checkout code
5039 uses : actions/checkout@v4
51-
52- - name : Set up Python ${{ matrix.python-version }}
40+ - name : Set up Python
5341 uses : actions/setup-python@v5
5442 with :
55- python-version : ${{ matrix.python-version }}
56-
43+ python-version : ' 3.11'
5744 - name : Install dependencies
5845 run : |
5946 python -m pip install --upgrade pip
6047 pip install -e ".[dev]"
61-
6248 - name : Run unit tests
6349 run : pytest tests/ -v --tb=short
64-
6550 - name : Run tests with coverage
66- if : matrix.python-version == '3.11'
6751 run : |
6852 pytest tests/ --cov=src/shieldgents --cov-report=xml --cov-report=term
69-
7053 - name : Upload coverage to Codecov
71- if : matrix.python-version == '3.11'
7254 uses : codecov/codecov-action@v4
7355 with :
7456 file : ./coverage.xml
@@ -77,47 +59,38 @@ jobs:
7759 integration-tests :
7860 name : Integration Tests
7961 runs-on : ubuntu-latest
80-
8162 steps :
8263 - name : Checkout code
8364 uses : actions/checkout@v4
84-
8565 - name : Set up Python
8666 uses : actions/setup-python@v5
8767 with :
8868 python-version : ' 3.11'
89-
9069 - name : Install dependencies
9170 run : |
9271 python -m pip install --upgrade pip
9372 pip install -e ".[dev]"
94-
9573 - name : Run integration tests
9674 run : pytest tests/ -v -m integration --tb=short
9775 continue-on-error : true
9876
9977 security-check :
10078 name : Security Scanning
10179 runs-on : ubuntu-latest
102-
10380 steps :
10481 - name : Checkout code
10582 uses : actions/checkout@v4
106-
10783 - name : Set up Python
10884 uses : actions/setup-python@v5
10985 with :
11086 python-version : ' 3.11'
111-
11287 - name : Install dependencies
11388 run : |
11489 python -m pip install --upgrade pip
11590 pip install bandit safety
116-
11791 - name : Run Bandit security scan
11892 run : bandit -r src/ -f json -o bandit-report.json
11993 continue-on-error : true
120-
12194 - name : Run Safety check
12295 run : safety check --json
12396 continue-on-error : true
@@ -126,29 +99,215 @@ jobs:
12699 name : Build Package
127100 runs-on : ubuntu-latest
128101 needs : [lint, test]
129-
130102 steps :
131103 - name : Checkout code
132104 uses : actions/checkout@v4
133-
134105 - name : Set up Python
135106 uses : actions/setup-python@v5
136107 with :
137108 python-version : ' 3.11'
138-
139109 - name : Install build dependencies
140110 run : |
141111 python -m pip install --upgrade pip
142112 pip install build twine
143-
144113 - name : Build package
145114 run : python -m build
146-
147115 - name : Check package
148116 run : twine check dist/*
149-
150117 - name : Upload artifacts
151118 uses : actions/upload-artifact@v4
152119 with :
153120 name : dist-packages
154121 path : dist/
122+
123+ # ------------------------------
124+ # Telegram notifications
125+ # ------------------------------
126+
127+ notify-telegram-pr-opened :
128+ name : Notify Telegram (PR Opened)
129+ runs-on : ubuntu-latest
130+ if : github.event_name == 'pull_request'
131+ steps :
132+ - name : Send Telegram message (PR opened)
133+ continue-on-error : true
134+ env :
135+ TG_TOKEN : ${{ secrets.TELEGRAM_BOT_TOKEN }}
136+ CHAT_ID : ${{ secrets.TELEGRAM_CHAT_ID }}
137+ REPO : ${{ github.repository }}
138+ ACTOR : ${{ github.actor }}
139+ PR_NUM : ${{ github.event.pull_request.number }}
140+ PR_TITLE : ${{ github.event.pull_request.title }}
141+ PR_URL : ${{ github.event.pull_request.html_url }}
142+ HEAD_BRANCH : ${{ github.event.pull_request.head.ref }}
143+ BASE_BRANCH : ${{ github.event.pull_request.base.ref }}
144+ RUN_URL : ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
145+ run : |
146+ # Check if secrets are set
147+ if [ -z "$TG_TOKEN" ] || [ -z "$CHAT_ID" ]; then
148+ echo "ERROR: TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID is not set"
149+ echo "TG_TOKEN length: ${#TG_TOKEN}"
150+ echo "CHAT_ID length: ${#CHAT_ID}"
151+ exit 0
152+ fi
153+
154+ set -euo pipefail
155+ API_URL="https://api.telegram.org/bot${TG_TOKEN}/sendMessage"
156+ MSG="📋 <b>New Pull Request</b>
157+ Repo: <code>${REPO}</code>
158+ By: <b>${ACTOR}</b>
159+ PR: <b>#${PR_NUM}</b> — ${PR_TITLE}
160+ Branch: <code>${HEAD_BRANCH}</code> → <code>${BASE_BRANCH}</code>
161+ Link: ${PR_URL}
162+ Run: ${RUN_URL}"
163+
164+ HTTP_CODE=$(curl -sS -w "%{http_code}" -o /tmp/resp.json "$API_URL" \
165+ -d "chat_id=${CHAT_ID}" \
166+ -d "parse_mode=HTML" \
167+ -d "disable_web_page_preview=true" \
168+ --data-urlencode "text=${MSG}")
169+ echo "Telegram response:"; cat /tmp/resp.json; echo; echo "HTTP ${HTTP_CODE}"
170+ [ "$HTTP_CODE" = "200" ] || exit 1
171+
172+ notify-telegram-tests-passed :
173+ name : Notify Telegram (Tests Passed)
174+ runs-on : ubuntu-latest
175+ needs : [lint, test]
176+ if : ${{ always() && needs.lint.result == 'success' && needs.test.result == 'success' }}
177+ steps :
178+ - name : Send Telegram message (tests passed)
179+ continue-on-error : true
180+ env :
181+ TG_TOKEN : ${{ secrets.TELEGRAM_BOT_TOKEN }}
182+ CHAT_ID : ${{ secrets.TELEGRAM_CHAT_ID }}
183+ REPO : ${{ github.repository }}
184+ ACTOR : ${{ github.actor }}
185+ EVENT : ${{ github.event_name }}
186+ REF : ${{ github.ref }}
187+ SHA : ${{ github.sha }}
188+ RUN_URL : ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
189+ run : |
190+ # Check if secrets are set
191+ if [ -z "$TG_TOKEN" ] || [ -z "$CHAT_ID" ]; then
192+ echo "ERROR: TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID is not set"
193+ echo "Please add these secrets in GitHub repo Settings -> Secrets and variables -> Actions"
194+ echo "TG_TOKEN length: ${#TG_TOKEN}"
195+ echo "CHAT_ID length: ${#CHAT_ID}"
196+ exit 0
197+ fi
198+
199+ set -euo pipefail
200+ API_URL="https://api.telegram.org/bot${TG_TOKEN}/sendMessage"
201+
202+ # Format message based on event type
203+ if [ "$EVENT" = "pull_request" ]; then
204+ PR_NUM="${{ github.event.pull_request.number }}"
205+ PR_TITLE="${{ github.event.pull_request.title }}"
206+ PR_URL="${{ github.event.pull_request.html_url }}"
207+ MSG="✅ <b>Tests Passed</b>
208+ Repo: <code>${REPO}</code>
209+ By: <b>${ACTOR}</b>
210+ PR: <b>#${PR_NUM}</b> — ${PR_TITLE}
211+ Link: ${PR_URL}
212+ Run: ${RUN_URL}"
213+ else
214+ BRANCH="${REF#refs/heads/}"
215+ MSG="✅ <b>Tests Passed</b>
216+ Repo: <code>${REPO}</code>
217+ By: <b>${ACTOR}</b>
218+ Branch: <code>${BRANCH}</code>
219+ Commit: <code>${SHA:0:7}</code>
220+ Run: ${RUN_URL}"
221+ fi
222+
223+ HTTP_CODE=$(curl -sS -w "%{http_code}" -o /tmp/resp.json "$API_URL" \
224+ -d "chat_id=${CHAT_ID}" \
225+ -d "parse_mode=HTML" \
226+ -d "disable_web_page_preview=true" \
227+ --data-urlencode "text=${MSG}")
228+ echo "Telegram response:"; cat /tmp/resp.json; echo; echo "HTTP ${HTTP_CODE}"
229+ [ "$HTTP_CODE" = "200" ] || exit 1
230+
231+ notify-telegram-tests-failed :
232+ name : Notify Telegram (Tests Failed)
233+ runs-on : ubuntu-latest
234+ needs : [lint, test]
235+ if : ${{ always() && (needs.lint.result == 'failure' || needs.test.result == 'failure') }}
236+ steps :
237+ - name : Send Telegram message (tests failed)
238+ continue-on-error : true
239+ env :
240+ TG_TOKEN : ${{ secrets.TELEGRAM_BOT_TOKEN }}
241+ CHAT_ID : ${{ secrets.TELEGRAM_CHAT_ID }}
242+ REPO : ${{ github.repository }}
243+ ACTOR : ${{ github.actor }}
244+ EVENT : ${{ github.event_name }}
245+ REF : ${{ github.ref }}
246+ SHA : ${{ github.sha }}
247+ RUN_URL : ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
248+ run : |
249+ set -euo pipefail
250+ API_URL="https://api.telegram.org/bot${TG_TOKEN}/sendMessage"
251+
252+ # Format message based on event type
253+ if [ "$EVENT" = "pull_request" ]; then
254+ PR_NUM="${{ github.event.pull_request.number }}"
255+ PR_TITLE="${{ github.event.pull_request.title }}"
256+ PR_URL="${{ github.event.pull_request.html_url }}"
257+ MSG="❌ <b>Tests Failed</b>
258+ Repo: <code>${REPO}</code>
259+ By: <b>${ACTOR}</b>
260+ PR: <b>#${PR_NUM}</b> — ${PR_TITLE}
261+ Link: ${PR_URL}
262+ Run: ${RUN_URL}"
263+ else
264+ BRANCH="${REF#refs/heads/}"
265+ MSG="❌ <b>Tests Failed</b>
266+ Repo: <code>${REPO}</code>
267+ By: <b>${ACTOR}</b>
268+ Branch: <code>${BRANCH}</code>
269+ Commit: <code>${SHA:0:7}</code>
270+ Run: ${RUN_URL}"
271+ fi
272+
273+ HTTP_CODE=$(curl -sS -w "%{http_code}" -o /tmp/resp.json "$API_URL" \
274+ -d "chat_id=${CHAT_ID}" \
275+ -d "parse_mode=HTML" \
276+ -d "disable_web_page_preview=true" \
277+ --data-urlencode "text=${MSG}")
278+ echo "Telegram response:"; cat /tmp/resp.json; echo; echo "HTTP ${HTTP_CODE}"
279+ [ "$HTTP_CODE" = "200" ] || exit 1
280+
281+ notify-telegram-merged :
282+ name : Notify Telegram (PR merged)
283+ runs-on : ubuntu-latest
284+ if : github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true
285+ steps :
286+ - name : Send Telegram message (merged)
287+ continue-on-error : true
288+ env :
289+ TG_TOKEN : ${{ secrets.TELEGRAM_BOT_TOKEN }}
290+ CHAT_ID : ${{ secrets.TELEGRAM_CHAT_ID }}
291+ REPO : ${{ github.repository }}
292+ ACTOR : ${{ github.event.pull_request.merged_by.login }}
293+ PR_NUM : ${{ github.event.pull_request.number }}
294+ PR_TITLE : ${{ github.event.pull_request.title }}
295+ PR_URL : ${{ github.event.pull_request.html_url }}
296+ BASE_BRANCH : ${{ github.event.pull_request.base.ref }}
297+ HEAD_BRANCH : ${{ github.event.pull_request.head.ref }}
298+ run : |
299+ set -euo pipefail
300+ API_URL="https://api.telegram.org/bot${TG_TOKEN}/sendMessage"
301+ MSG="✅ <b>PR Merged</b>
302+ Repo: <code>${REPO}</code>
303+ By: <b>${ACTOR}</b>
304+ PR: <b>#${PR_NUM}</b> — ${PR_TITLE}
305+ Branch: <code>${HEAD_BRANCH}</code> → <code>${BASE_BRANCH}</code>
306+ Link: ${PR_URL}"
307+ HTTP_CODE=$(curl -sS -w "%{http_code}" -o /tmp/resp.json "$API_URL" \
308+ -d "chat_id=${CHAT_ID}" \
309+ -d "parse_mode=HTML" \
310+ -d "disable_web_page_preview=true" \
311+ --data-urlencode "text=${MSG}")
312+ echo "Telegram response:"; cat /tmp/resp.json; echo; echo "HTTP ${HTTP_CODE}"
313+ [ "$HTTP_CODE" = "200" ] || exit 1
0 commit comments