Skip to content

Commit 26d3c5c

Browse files
authored
Merge pull request #112 from logzio/feat/dependencies
[CI] Automatic dependency updates
2 parents 5bfdbaa + 16bccf0 commit 26d3c5c

File tree

9 files changed

+556
-15
lines changed

9 files changed

+556
-15
lines changed

.github/dependabot.yaml

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,40 @@
1-
# To get started with Dependabot version updates, you'll need to specify which
2-
# package ecosystems to update and where the package manifests are located.
3-
# Please see the documentation for all configuration options:
4-
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
1+
# Dependabot configuration for automated dependency updates
2+
# See: https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
53

64
version: 2
75
updates:
8-
- package-ecosystem: "pip" # See documentation for possible values
9-
directory: "/" # Location of package manifests
6+
- package-ecosystem: "pip"
7+
directory: "/"
108
schedule:
119
interval: "weekly"
10+
day: "monday"
11+
time: "09:00"
12+
timezone: "Asia/Jerusalem"
13+
groups:
14+
python-dependencies:
15+
patterns:
16+
- "*"
17+
commit-message:
18+
prefix: "deps"
19+
labels:
20+
- "dependencies"
21+
- "python"
22+
open-pull-requests-limit: 5
23+
1224
- package-ecosystem: "github-actions"
13-
# Workflow files stored in the default location of `.github/workflows`. (You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.)
1425
directory: "/"
1526
schedule:
16-
# Check for updates to GitHub Actions every weekday
1727
interval: "weekly"
28+
day: "monday"
29+
time: "09:00"
30+
timezone: "Asia/Jerusalem"
31+
groups:
32+
github-actions:
33+
patterns:
34+
- "*"
35+
commit-message:
36+
prefix: "ci"
37+
labels:
38+
- "dependencies"
39+
- "github-actions"
40+
open-pull-requests-limit: 5

.github/workflows/ci.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
6+
permissions:
7+
contents: read
8+
9+
jobs:
10+
test:
11+
name: Test (Python ${{ matrix.python-version }})
12+
runs-on: ubuntu-latest
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Set up Python ${{ matrix.python-version }}
25+
uses: actions/setup-python@v5
26+
with:
27+
python-version: ${{ matrix.python-version }}
28+
cache: "pip"
29+
30+
- name: Install dependencies
31+
run: |
32+
python -m pip install --upgrade pip
33+
pip install -r requirements.txt
34+
pip install pytest pytest-cov future requests
35+
36+
- name: Install package in development mode
37+
run: pip install -e .
38+
39+
- name: Run unit tests with coverage
40+
run: |
41+
pytest --cov-report=term-missing --cov=logzio tests/ -v --ignore=tests/e2e/
42+
43+
- name: Upload coverage report
44+
if: matrix.python-version == '3.11'
45+
uses: actions/upload-artifact@v4
46+
with:
47+
name: coverage-report
48+
path: .coverage
49+
retention-days: 5
50+
51+
e2e-integration:
52+
name: E2E Integration Test
53+
runs-on: ubuntu-latest
54+
needs: [test]
55+
56+
steps:
57+
- name: Checkout code
58+
uses: actions/checkout@v4
59+
with:
60+
fetch-depth: 0
61+
62+
- name: Set up Python
63+
uses: actions/setup-python@v5
64+
with:
65+
python-version: "3.11"
66+
cache: "pip"
67+
68+
- name: Install dependencies
69+
run: |
70+
python -m pip install --upgrade pip
71+
pip install -r requirements.txt
72+
pip install pytest requests
73+
74+
- name: Install package in development mode
75+
run: pip install -e .
76+
77+
- name: Generate unique ENV_ID
78+
id: env-id
79+
run: echo "value=e2e-${{ github.run_id }}-${{ github.run_attempt }}" >> $GITHUB_OUTPUT
80+
81+
- name: Run E2E integration test
82+
env:
83+
LOGZIO_TOKEN: ${{ secrets.LOGZIO_TOKEN }}
84+
LOGZIO_API_KEY: ${{ secrets.LOGZIO_API_KEY }}
85+
ENV_ID: ${{ steps.env-id.outputs.value }}
86+
run: |
87+
pytest tests/e2e/test_logzio_e2e.py -v --tb=long
88+
89+
ci-success:
90+
name: CI Success
91+
runs-on: ubuntu-latest
92+
needs: [test, e2e-integration]
93+
if: always()
94+
steps:
95+
- name: Check all jobs passed
96+
run: |
97+
if [[ "${{ needs.test.result }}" != "success" ]]; then
98+
echo "Test job failed"
99+
exit 1
100+
fi
101+
if [[ "${{ needs.e2e-integration.result }}" != "success" ]]; then
102+
echo "E2E integration job failed"
103+
exit 1
104+
fi
105+
echo "All CI checks passed! ✅"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Dependabot Auto-Merge
2+
3+
# This workflow runs AFTER CI completes for Dependabot PRs.
4+
# It waits for CI to pass, then enables auto-merge.
5+
6+
on:
7+
workflow_run:
8+
workflows: ["CI"]
9+
types:
10+
- completed
11+
12+
permissions:
13+
contents: write
14+
pull-requests: write
15+
16+
jobs:
17+
auto-merge:
18+
name: Auto-Merge Dependabot PR
19+
runs-on: ubuntu-latest
20+
# Run if:
21+
# 1. CI passed
22+
# 2. It was triggered by Dependabot
23+
# 3. It was a pull request
24+
if: |
25+
github.event.workflow_run.conclusion == 'success' &&
26+
github.event.workflow_run.actor.login == 'dependabot[bot]' &&
27+
github.event.workflow_run.event == 'pull_request'
28+
29+
steps:
30+
- name: Checkout for metadata
31+
uses: actions/checkout@v4
32+
33+
- name: Fetch Dependabot metadata
34+
id: metadata
35+
uses: dependabot/fetch-metadata@v2
36+
with:
37+
github-token: "${{ secrets.GITHUB_TOKEN }}"
38+
39+
- name: Auto-merge patch/minor updates
40+
if: |
41+
steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
42+
steps.metadata.outputs.update-type == 'version-update:semver-minor'
43+
run: |
44+
echo "Enabling auto-merge for ${{ steps.metadata.outputs.dependency-names }} (${{ steps.metadata.outputs.update-type }})"
45+
gh pr merge --auto --merge "$HEAD_BRANCH"
46+
env:
47+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48+
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
49+
50+
- name: Skip major updates
51+
if: steps.metadata.outputs.update-type == 'version-update:semver-major'
52+
run: |
53+
echo "Major version update for ${{ steps.metadata.outputs.dependency-names }} - review required"
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
name: Dependabot Notifications
2+
3+
# This workflow sends Slack notifications when CI completes for Dependabot PRs.
4+
# It uses workflow_run to trigger AFTER the CI workflow finishes.
5+
6+
7+
on:
8+
workflow_run:
9+
workflows: ["CI"]
10+
types:
11+
- completed
12+
13+
permissions:
14+
contents: read
15+
pull-requests: read
16+
actions: read
17+
18+
jobs:
19+
notify-success:
20+
name: Notify Success
21+
runs-on: ubuntu-latest
22+
if: |
23+
github.event.workflow_run.conclusion == 'success' &&
24+
github.event.workflow_run.actor.login == 'dependabot[bot]'
25+
26+
steps:
27+
- name: Get PR information
28+
id: pr-info
29+
uses: actions/github-script@v7
30+
with:
31+
script: |
32+
const { data: pullRequests } = await github.rest.pulls.list({
33+
owner: context.repo.owner,
34+
repo: context.repo.repo,
35+
state: 'open',
36+
head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}`
37+
});
38+
39+
if (pullRequests.length > 0) {
40+
const pr = pullRequests[0];
41+
core.setOutput('pr_number', pr.number);
42+
core.setOutput('pr_title', pr.title);
43+
core.setOutput('pr_url', pr.html_url);
44+
core.setOutput('found', 'true');
45+
} else {
46+
core.setOutput('found', 'false');
47+
}
48+
49+
- name: Send Slack notification (Success)
50+
if: steps.pr-info.outputs.found == 'true'
51+
run: |
52+
curl -X POST -H 'Content-type: application/json' --data '{
53+
"attachments": [{
54+
"color": "#36a64f",
55+
"blocks": [
56+
{
57+
"type": "header",
58+
"text": {"type": "plain_text", "text": "✅ Dependabot Update - CI Passed", "emoji": true}
59+
},
60+
{
61+
"type": "section",
62+
"fields": [
63+
{"type": "mrkdwn", "text": "*Repository:*\n${{ github.repository }}"},
64+
{"type": "mrkdwn", "text": "*PR:*\n<${{ steps.pr-info.outputs.pr_url }}|#${{ steps.pr-info.outputs.pr_number }}>"}
65+
]
66+
},
67+
{
68+
"type": "section",
69+
"text": {"type": "mrkdwn", "text": "${{ steps.pr-info.outputs.pr_title }}"}
70+
},
71+
{
72+
"type": "context",
73+
"elements": [{"type": "mrkdwn", "text": "Auto-merge enabled • logzio-python-handler CI"}]
74+
}
75+
]
76+
}]
77+
}' "$SLACK_WEBHOOK"
78+
env:
79+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
80+
81+
82+
notify-failure:
83+
name: Notify Failure
84+
runs-on: ubuntu-latest
85+
if: |
86+
github.event.workflow_run.conclusion == 'failure' &&
87+
github.event.workflow_run.actor.login == 'dependabot[bot]'
88+
89+
steps:
90+
- name: Get PR information
91+
id: pr-info
92+
uses: actions/github-script@v7
93+
with:
94+
script: |
95+
const { data: pullRequests } = await github.rest.pulls.list({
96+
owner: context.repo.owner,
97+
repo: context.repo.repo,
98+
state: 'open',
99+
head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}`
100+
});
101+
102+
if (pullRequests.length > 0) {
103+
const pr = pullRequests[0];
104+
core.setOutput('pr_number', pr.number);
105+
core.setOutput('pr_title', pr.title);
106+
core.setOutput('pr_url', pr.html_url);
107+
core.setOutput('found', 'true');
108+
} else {
109+
core.setOutput('found', 'false');
110+
}
111+
112+
- name: Get workflow run URL
113+
id: run-url
114+
run: |
115+
echo "url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}" >> $GITHUB_OUTPUT
116+
117+
- name: Send Slack notification (Failure)
118+
if: steps.pr-info.outputs.found == 'true'
119+
run: |
120+
curl -X POST -H 'Content-type: application/json' --data '{
121+
"attachments": [{
122+
"color": "#ff0000",
123+
"blocks": [
124+
{
125+
"type": "header",
126+
"text": {"type": "plain_text", "text": "🚨 Dependabot Update - CI Failed", "emoji": true}
127+
},
128+
{
129+
"type": "section",
130+
"fields": [
131+
{"type": "mrkdwn", "text": "*Repository:*\n${{ github.repository }}"},
132+
{"type": "mrkdwn", "text": "*PR:*\n<${{ steps.pr-info.outputs.pr_url }}|#${{ steps.pr-info.outputs.pr_number }}>"}
133+
]
134+
},
135+
{
136+
"type": "section",
137+
"text": {"type": "mrkdwn", "text": "${{ steps.pr-info.outputs.pr_title }}\n\n<${{ steps.run-url.outputs.url }}|View CI Run> to investigate"}
138+
},
139+
{
140+
"type": "context",
141+
"elements": [{"type": "mrkdwn", "text": "Manual intervention required • logzio-python-handler CI"}]
142+
}
143+
]
144+
}]
145+
}' "$SLACK_WEBHOOK"
146+
env:
147+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
148+
149+
notify-merged:
150+
name: Notify Merged
151+
runs-on: ubuntu-latest
152+
if: |
153+
github.event.workflow_run.conclusion == 'success' &&
154+
github.event.workflow_run.event == 'push' &&
155+
contains(github.event.workflow_run.head_commit.message, 'dependabot')
156+
157+
steps:
158+
- name: Send Slack notification (Merged)
159+
run: |
160+
curl -X POST -H 'Content-type: application/json' --data '{
161+
"attachments": [{
162+
"color": "#2eb886",
163+
"blocks": [
164+
{
165+
"type": "header",
166+
"text": {"type": "plain_text", "text": "🎉 Dependencies Updated Successfully", "emoji": true}
167+
},
168+
{
169+
"type": "section",
170+
"fields": [
171+
{"type": "mrkdwn", "text": "*Repository:*\n${{ github.repository }}"},
172+
{"type": "mrkdwn", "text": "*Commit:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.event.workflow_run.head_sha }}|${{ github.event.workflow_run.head_sha }}>"}
173+
]
174+
},
175+
{
176+
"type": "context",
177+
"elements": [{"type": "mrkdwn", "text": "Merged to main • logzio-python-handler CI"}]
178+
}
179+
]
180+
}]
181+
}' "$SLACK_WEBHOOK"
182+
env:
183+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
184+

0 commit comments

Comments
 (0)