Skip to content

Commit 3cb3a12

Browse files
ci: GitHub setup (#112)
1 parent 6cefb44 commit 3cb3a12

25 files changed

+912
-501
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
name: Bug report
3+
about: Bug report
4+
title: "<Area of the SDK>: <Short Description of issue>"
5+
labels: needs triage
6+
assignees: ''
7+
8+
---
9+
10+
**Describe the bug**
11+
A clear and concise description of what the bug is.
12+
13+
**To Reproduce**
14+
Steps to reproduce the behavior:
15+
1. Go to '...'
16+
2. Click on '....'
17+
3. Scroll down to '....'
18+
4. See error
19+
20+
**Expected behavior**
21+
A clear and concise description of what you expected to happen.
22+
23+
Links to related tickets or other context are welcome here.
24+
25+
**Screenshots**
26+
If applicable, add screenshots to help explain your problem.
27+
28+
**Environment (please complete the following information):**
29+
- OS: [e.g. Linux/Windows/macOS etc]
30+
- SDK version: [e.g. 10.5.2]
31+
- Python version: [e.g. 3.0.0]
32+
33+
**Logs**
34+
If applicable, include relevant logs or error messages here (please use code blocks to format properly).
35+
36+
**Possible Solution**
37+
If you have suggestions for how the issue might be resolved or investigated, please describe them here.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
name: Feature request
3+
about: A new feature for this SDK
4+
title: "<Area of the SDK>: <Short Description of new feature>"
5+
labels: needs triage
6+
assignees: ''
7+
8+
---
9+
10+
**Please describe your new feature request**
11+
A clear and concise description of what the problem is. Example: I'm always frustrated when [...]
12+
13+
**Describe the solution you'd like**
14+
A clear and concise description of what you want to happen.
15+
16+
Links to related tickets or other information are welcome here.
17+
18+
**Describe alternatives you've considered**
19+
A clear and concise description of any alternative solutions or features you've considered.
20+
21+
**Additional context**
22+
Add any other context or screenshots about the feature request here.

.github/dependabot.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
version: 2
2+
updates:
3+
# Python dependencies updates config
4+
- package-ecosystem: "setuptools"
5+
directory: "/"
6+
schedule:
7+
interval: "monthly"
8+
commit-message:
9+
prefix: "chore"
10+
include: "scope"
11+
12+
# Github Actions dependencies updates config
13+
- package-ecosystem: "github-actions"
14+
directory: "/"
15+
schedule:
16+
interval: "monthly"
17+
commit-message:
18+
prefix: "chore"
19+
include: "scope"

.github/workflows/pr.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: "Pull-Request Check"
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- edited
8+
- synchronize
9+
10+
jobs:
11+
main:
12+
name: Validate PR title
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: amannn/action-semantic-pull-request@v5
16+
id: lint_pr_title
17+
env:
18+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19+
20+
- uses: marocchino/sticky-pull-request-comment@v2
21+
# When the previous steps fails, the workflow would stop. By adding this
22+
# condition you can continue the execution with the populated error message.
23+
if: always() && (steps.lint_pr_title.outputs.error_message != null)
24+
with:
25+
header: pr-title-lint-error
26+
message: |
27+
We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.
28+
Details:
29+
```
30+
${{ steps.lint_pr_title.outputs.error_message }}
31+
```
32+
# Delete a previous comment when the issue has been resolved
33+
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
34+
uses: marocchino/sticky-pull-request-comment@v2
35+
with:
36+
header: pr-title-lint-error
37+
delete: true

.github/workflows/python-checks.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Python Checks
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
9+
jobs:
10+
test:
11+
name: Format, lint & tests
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14.0-alpha.7"]
16+
17+
steps:
18+
- uses: actions/checkout@v3
19+
20+
- name: Set up Python ${{ matrix.python-version }}
21+
uses: actions/setup-python@v4
22+
with:
23+
python-version: ${{ matrix.python-version }}
24+
check-latest: true
25+
26+
- name: Install dependencies
27+
run: |
28+
python -m pip install --upgrade pip
29+
pip install black flake8 coverage .[dev]
30+
31+
- name: Check formatting with black
32+
run: |
33+
black --check python3/
34+
35+
# TODO: Re-enable linting
36+
# - name: Lint with flake8
37+
# run: |
38+
# flake8 python3/
39+
40+
- name: Run tests with coverage
41+
env:
42+
RAYGUN_API_KEY: ${{ secrets.RAYGUN_API_KEY }}
43+
run: |
44+
coverage run --source=python3 -m unittest discover python3/tests
45+
coverage report -m

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@ nosetests.xml
4646

4747
# IntelliJ
4848
.idea
49+
50+
# Python local env
51+
.venv

pull_request_template.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
### Description :memo:
2+
3+
**Purpose**:
4+
5+
<!-- What issue does this PR address or what feature does it implement? -->
6+
7+
**Approach**:
8+
9+
<!-- How does this PR tackle the problem? -->
10+
11+
**Type of change**
12+
13+
<!-- Select all that are relevant -->
14+
15+
- [ ] `fix:` Bug fix (non-breaking change which fixes an issue)
16+
- [ ] `feat:` New feature (non-breaking change which adds functionality)
17+
- [ ] `chore:` Chore task, release or small impact change
18+
- [ ] `ci:` CI configuration change
19+
- [ ] Other type of change (specify)
20+
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
21+
- [ ] This change requires a documentation update
22+
23+
**Updates**
24+
25+
<!-- List of updates -->
26+
27+
**Related issues**
28+
29+
<!-- Issue numbers or links -->
30+
31+
### Test plan :test_tube:
32+
33+
<!-- Provide guidance for how to QA your proposed changes. This is not only for a test but also useful for a reviewer. -->
34+
35+
### Author to check :eyeglasses:
36+
37+
- [ ] Project and all contained modules builds successfully
38+
- [ ] Self-/dev-tested
39+
- [ ] Unit/UI/Automation/Integration tests provided where applicable
40+
- [ ] Code is written to standards
41+
- [ ] Appropriate documentation written (code comments, internal docs)
42+
43+
### Reviewer to check :heavy_check_mark:
44+
45+
- [ ] Project and all contained modules builds successfully
46+
- [ ] Change has been dev-/reviewer-tested, where possible
47+
- [ ] Unit/UI/Automation/Integration tests provided where applicable
48+
- [ ] Code is written to standards
49+
- [ ] Appropriate documentation written (code comments, internal docs)

python3/raygun4py/cli.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55

66
def main():
7-
usage = '\n raygun4py test <apikey>'
7+
usage = "\n raygun4py test <apikey>"
88
parser = OptionParser(usage=usage)
99

1010
_, args = parser.parse_args()
1111

1212
if len(args) < 2 or not isinstance(args[1], str):
13-
print('Please provide your API key')
13+
print("Please provide your API key")
1414
parser.print_help()
15-
elif args[0] == 'test':
15+
elif args[0] == "test":
1616
send_test_exception(args[1])
1717
else:
1818
print(f"Invalid command '{args[0]}'")
@@ -31,5 +31,6 @@ def send_test_exception(apikey):
3131
print("Success! Now check your Raygun dashboard at https://app.raygun.com")
3232
else:
3333
print(
34-
"Something went wrong - please check your API key or contact us for help. The response was:")
34+
"Something went wrong - please check your API key or contact us for help. The response was:"
35+
)
3536
print(response)

python3/raygun4py/http_utilities.py

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
def build_wsgi_compliant_request(request):
42
if not request:
53
return
@@ -9,60 +7,66 @@ def build_wsgi_compliant_request(request):
97
# httpRequest keys for RG API compat
108
# https://www.python.org/dev/peps/pep-3333/#environ-variables
119

12-
http_host = request.get('hostName') \
13-
or request.get('HTTP_HOST') \
14-
or "{}:{}".format(request.get('SERVER_NAME'), request.get('SERVER_PORT'))
10+
http_host = (
11+
request.get("hostName")
12+
or request.get("HTTP_HOST")
13+
or "{}:{}".format(request.get("SERVER_NAME"), request.get("SERVER_PORT"))
14+
)
1515

1616
if http_host is not None:
17-
http_host = http_host.replace(' ', '')
17+
http_host = http_host.replace(" ", "")
1818

1919
try:
20-
http_form = getattr(request, 'form', None) or request.get('form')
20+
http_form = getattr(request, "form", None) or request.get("form")
2121

2222
# fallback to wsgi.input
23-
if http_form is None and 'wsgi.input' in request:
23+
if http_form is None and "wsgi.input" in request:
2424
# we can assume WSGI keys inside this block
25-
content_length = int(request.get('CONTENT_LENGTH', 0))
25+
content_length = int(request.get("CONTENT_LENGTH", 0))
2626
if content_length:
27-
http_form = request['wsgi.input'].read(content_length)
27+
http_form = request["wsgi.input"].read(content_length)
2828

2929
rg_request = {
30-
'httpMethod': (request.get('httpMethod') or request.get('REQUEST_METHOD')),
31-
'url': (request.get('url') or request.get('PATH_INFO')),
32-
'hostName': http_host,
33-
'iPAddress': (request.get('ipAddress') or request.get('iPAddress') or request.get('REMOTE_ADDR')),
34-
'queryString': (request.get('queryString') or request.get('QUERY_STRING')),
35-
'headers': {}, # see below
36-
'form': http_form,
37-
'rawData': request.get('rawData')
30+
"httpMethod": (request.get("httpMethod") or request.get("REQUEST_METHOD")),
31+
"url": (request.get("url") or request.get("PATH_INFO")),
32+
"hostName": http_host,
33+
"iPAddress": (
34+
request.get("ipAddress")
35+
or request.get("iPAddress")
36+
or request.get("REMOTE_ADDR")
37+
),
38+
"queryString": (request.get("queryString") or request.get("QUERY_STRING")),
39+
"headers": {}, # see below
40+
"form": http_form,
41+
"rawData": request.get("rawData"),
3842
}
3943
except Exception:
4044
pass
4145

4246
# Header processing
43-
_headers = request.get('headers')
47+
_headers = request.get("headers")
4448
if _headers is None:
4549
# manually try to build up headers given known WSGI keys
4650
_headers = {
47-
'Content-Type': request.get('CONTENT_TYPE'),
48-
'Content-Length': request.get('CONTENT_LENGTH'),
51+
"Content-Type": request.get("CONTENT_TYPE"),
52+
"Content-Length": request.get("CONTENT_LENGTH"),
4953
}
5054

5155
for key, value in request.items():
52-
if key.startswith('HTTP_'):
56+
if key.startswith("HTTP_"):
5357
# 'HTTP_REFERER' => 'Referer'
5458
new_key = http_environ_var_to_header_key(key)
5559
_headers[new_key] = value
5660

57-
rg_request['headers'] = _headers
61+
rg_request["headers"] = _headers
5862

5963
return rg_request
6064

6165

6266
def http_environ_var_to_header_key(key):
6367
"turns HTTP_REFERER like keys into Referer"
64-
parts = key.split('_')
68+
parts = key.split("_")
6569
if parts[0] == "HTTP":
6670
parts.pop(0)
6771

68-
return '-'.join([x.title() for x in parts])
72+
return "-".join([x.title() for x in parts])

0 commit comments

Comments
 (0)