Skip to content

Commit b7755ab

Browse files
committed
adds github action
1 parent f6d0a3d commit b7755ab

File tree

4 files changed

+203
-44
lines changed

4 files changed

+203
-44
lines changed

.github/workflows/deploy.yml

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
name: Resurgo.AI - Outage Recovery Simulator
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
jobs:
8+
validate-repository:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: write
12+
steps:
13+
- name: Declare RCA skipped - forced push
14+
uses: actions/github-script@v7
15+
if: github.event.forced
16+
with:
17+
script: |
18+
const message = `**Resurgo.AI:** Root Cause Analysis (RCA) is skipped due to a forced push. Please use a regular push to enable RCA.`
19+
await github.rest.repos.createCommitComment({
20+
...context.repo,
21+
commit_sha: context.sha,
22+
body: message,
23+
});
24+
console.error(message)
25+
process.exit(1)
26+
27+
- name: Declare RCA skipped - private repo
28+
if: github.event.repository.private
29+
uses: actions/github-script@v7
30+
with:
31+
script: |
32+
const message = `**Resurgo.AI:** RCA workflow unavailable for private repositories.\n\n`
33+
`RCA workflow unavailable for private repositories. Set the repository to 'Public' and re-merge changes to enable RCA.`;
34+
await github.rest.repos.createCommitComment({
35+
...context.repo,
36+
commit_sha: context.sha,
37+
body: message
38+
});
39+
console.error(message)
40+
process.exit(1)
41+
42+
- name: Declare RCA skipped - workflow re-run
43+
if: github.run_attempt != 1
44+
uses: actions/github-script@v7
45+
with:
46+
script: |
47+
const message = `**Resurgo.AI:** RCA workflow unavailable for workflow re-runs.`
48+
await github.rest.repos.createCommitComment({
49+
...context.repo,
50+
commit_sha: context.sha,
51+
body: message
52+
});
53+
console.error(message)
54+
process.exit(1)
55+
56+
deploy:
57+
needs: validate-repository
58+
permissions:
59+
contents: write
60+
runs-on: ubuntu-latest
61+
outputs:
62+
artifact-url: ${{ steps.artifact-upload-step.outputs.artifact-url }}
63+
steps:
64+
65+
- name: Add commit comment
66+
uses: actions/github-script@v7
67+
with:
68+
script: |
69+
await github.rest.repos.createCommitComment({
70+
...context.repo,
71+
commit_sha: context.sha,
72+
body: `**Resurgo.AI:** Deployment in progress. Stay tuned for updates.`
73+
});
74+
75+
- name: Checkout code in 'before' state
76+
uses: actions/checkout@v4
77+
with:
78+
ref: ${{ github.event.before }}
79+
80+
- uses: actions/setup-python@v5
81+
with:
82+
python-version: '3.12'
83+
84+
- name: Simulate load before deploy
85+
run: |
86+
echo "Log for deploy ${{ github.event.before }}..${{ github.event.after }}" > app.log
87+
pip install -r requirements.txt
88+
PYTHONPATH=. python tests/user.py # writes logs for 50..100 requests to app.log
89+
mv app.log ..
90+
91+
- name: Checkout code in 'afer' state
92+
uses: actions/checkout@v4
93+
with:
94+
ref: ${{ github.event.after }}
95+
96+
- name: Simulate load after deploy
97+
run: |
98+
pip install -r requirements.txt
99+
mv ../app.log .
100+
PYTHONPATH=. python tests/user.py # writes logs for 50..100 requests to app.log
101+
102+
- name: Upload Artifact
103+
uses: actions/upload-artifact@v4
104+
id: artifact-upload-step
105+
with:
106+
name: Resurgo.AI-log-${{github.run_id}}-${{github.run_attempt}}
107+
path: app.log
108+
109+
- name: Deploy Error Handler
110+
id: deploy-error-handler
111+
if: failure() && !cancelled()
112+
uses: actions/github-script@v7
113+
with:
114+
script: |
115+
core.setOutput('happened', 'true')
116+
await github.rest.repos.createCommitComment({
117+
...context.repo,
118+
commit_sha: context.sha,
119+
body: `**Resurgo.AI:**\n\n` +
120+
`A critical error occurred during deployment, preventing RCA.\n\n` +
121+
`Recommended actions:\n\n` +
122+
` * Review the [workflow run logs](https://github.com/${context.repository}/actions/runs/${context.run_id}) for details.\n` +
123+
` * Address any issues introduced in this deployment.\n` +
124+
` * Push a corrected changeset.`
125+
});
126+
process.exit(1)
127+
128+
root-cause-analys:
129+
needs: deploy
130+
permissions:
131+
contents: write
132+
id-token: write
133+
runs-on: ubuntu-latest
134+
135+
steps:
136+
- name: Notify Resurgo orchestrator
137+
uses: actions/github-script@v7
138+
with:
139+
script: |
140+
const audience = 'https://resurgo.ai';
141+
const id_token = await core.getIDToken(audience);
142+
const response = await fetch('https://github.resurgo.ai/workflow', {
143+
method: "POST",
144+
headers: {
145+
"Authorization": `Bearer ${id_token}`,
146+
"X-Resurgo-Api-Version": "2024-11-17"
147+
}
148+
});
149+
150+
if (!response.ok) {
151+
console.error(`Failed to initiate the Resurgo.AI workflow. Error ${response.status}: ${response.statusText}.`);
152+
process.exit(1);
153+
}
154+
155+
- name: Add commit comment
156+
uses: actions/github-script@v7
157+
with:
158+
script: |
159+
await github.rest.repos.createCommitComment({
160+
...context.repo,
161+
commit_sha: context.sha,
162+
body: `**Resurgo.AI:**\n\n` +
163+
`Logs uploaded as [Resurgo.AI-log-${{github.run_id}}-${{github.run_attempt}}](${{ needs.deploy.outputs.artifact-url }}).\n\n` +
164+
`Orchestrator notified. Awaiting worker assignment.`
165+
});
166+
await core.summary
167+
.addHeading('RCA initiated successfully')
168+
.addRaw('Proggress updates and results will appear as comments under the last pushed commit: ')
169+
.addLink(context.sha, context.payload.head_commit.url)
170+
.write()
171+
172+
- name: RCA Error Handler
173+
id: deploy-error
174+
if: failure() && !cancelled() && steps.deploy-error-handler.outputs.happened != 'true'
175+
uses: actions/github-script@v7
176+
with:
177+
script: |
178+
await github.rest.repos.createCommitComment({
179+
...context.repo,
180+
commit_sha: context.sha,
181+
body: `**Resurgo.AI:**\n\n` +
182+
`A critical error occurred while initiating Root Cause Analysis (RCA).\n\n` +
183+
`No further actions will be taken for this deployment.`
184+
});
185+
process.exit(1);

app.log

Lines changed: 0 additions & 32 deletions
This file was deleted.

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
flask
22
logging
3+
pyyaml

tests/user.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
11
import unittest
22
from app import create_app
3+
import random
34

45
class TestUserAPI(unittest.TestCase):
56

67
def setUp(self):
78
self.app = create_app().test_client()
89

910
def test_multiple_get_requests(self):
10-
# Existing user
11-
for _ in range(10):
12-
response = self.app.get('/user/1')
13-
self.assertEqual(response.status_code, 200)
14-
data = response.get_json()
15-
self.assertEqual(data['id'], 1)
16-
17-
# Non-existing user
18-
for _ in range(2):
19-
response = self.app.get('/user/999')
20-
self.assertEqual(response.status_code, 404)
11+
# Simulate up to 100 requests, randomly triggering 404
12+
for _ in range(random.randint(50, 100)):
13+
try:
14+
# Around 2% of 400 - Not found
15+
if random.random() < 0.02: # 2% chance
16+
response = self.app.get('/user/999')
17+
self.assertEqual(response.status_code, 404)
18+
# Around 98% of 200 - Ok
19+
else:
20+
response = self.app.get('/user/1')
21+
self.assertEqual(response.status_code, 200)
22+
data = response.get_json()
23+
self.assertEqual(data['id'], 1)
24+
except Exception as e:
25+
print(f"Error in sampling attempt: {e}")
2126

2227
if __name__ == '__main__':
23-
unittest.main()
28+
unittest.main(exit=False)

0 commit comments

Comments
 (0)