-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path.gitlab-ci.yml
More file actions
138 lines (127 loc) · 4.44 KB
/
.gitlab-ci.yml
File metadata and controls
138 lines (127 loc) · 4.44 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
127
128
129
130
131
132
133
134
135
136
137
workflow:
rules:
# Don't run simple push pipelines
- if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH
when: never
# Allow to interrupt pipelines on merge request if a new commit arrives
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
auto_cancel:
on_new_commit: interruptible
# Do not interrupt pipelines on main
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
auto_cancel:
on_new_commit: none
# Suppress certain warnings
variables:
PIPENV_VERBOSITY: -1
stages:
- test
- gate
formatting:
stage: test
tags:
- test
script:
# Use black to verify the correct formatting of all files
- black --check .
interruptible: true
pytest:
stage: test
tags:
- test
script:
# Use most recent version from Pipfile
- poetry install --no-root
# Run all unit tests with coverage
- poetry run coverage run -m pytest
# Cobertura XML for MR diff line-by-line coverage visualization.
# Produced **first** so that it exists even when the `--fail-under`
# checks below abort the job — otherwise GitLab would have no
# coverage report to annotate the MR diff with in a failing build,
# which is exactly when the reviewer wants to see it. Paths inside
# the XML are repo-relative (pyproject.toml `[tool.coverage.run]
# relative_files = true`) so GitLab can match them to the diff.
# The -o target matches the `reports.coverage_report.path` below.
- coverage xml -o coverage/cobertura-coverage.xml
# Generate human-readable reports; both enforce the 80% floor.
- coverage html --fail-under=80
- cp -r htmlcov htmlcov-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
- coverage json --fail-under=80
- cp coverage.json coverage-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA.json
# Print total line so GitLab can parse the coverage percentage for the badge
- coverage report
# Regex for GitLab to extract the coverage percentage from the job log
coverage: '/(?i)total.*?(\d+(?:\.\d+)?)%/'
interruptible: true
artifacts:
# Take whole HTML folder and the json report
name: "coverage-report-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA"
# Upload artifacts / reports even when the job fails — the
# coverage XML is specifically valuable on failing builds because
# it shows the reviewer which newly-changed lines are not covered.
when: always
paths:
- htmlcov-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA/*
- coverage-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA.json
expire_in: 1 week
reports:
# Cobertura report: GitLab shows covered/uncovered lines in the MR diff
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
no-unreviewed-tests:
stage: gate
tags:
- test
script:
- poetry install --no-root
# Collect (--co) all tests marked needs_review_new or needs_review_modified
# without running them. If any exist, the MR still contains AI-generated or
# AI-modified tests that have not been reviewed — fail the pipeline.
- |
BLOCKED=0
NEW=$(poetry run pytest -m needs_review_new --co -q 2>/dev/null | grep '::' || true)
if [ -n "$NEW" ]; then
echo "ERROR: The following AI-generated tests need full review (needs_review_new):"
echo "$NEW"
echo ""
BLOCKED=1
fi
MODIFIED=$(poetry run pytest -m needs_review_modified --co -q 2>/dev/null | grep '::' || true)
if [ -n "$MODIFIED" ]; then
echo "ERROR: The following AI-modified tests need review (needs_review_modified)."
echo "Check the '# -- begin/end AI-modified --' sections in each method:"
echo "$MODIFIED"
echo ""
BLOCKED=1
fi
if [ "$BLOCKED" -eq 1 ]; then
echo "Remove the marker(s) after reviewing to unblock the merge."
exit 1
fi
echo "No unreviewed tests found — gate passed."
interruptible: true
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
check-coverage:
stage: test
tags:
- test
variables:
MIN_COVERAGE_NEW: "90"
MIN_COVERAGE_OLD: "81"
COVERAGE_EPSILON: "3.14"
dependencies:
- pytest
script:
- ./ci/check-coverage.sh
needs:
- job: pytest
- project: $CI_PROJECT_PATH
job: pytest
ref: $CI_DEFAULT_BRANCH
artifacts: true
rules:
- if: $CI_COMMIT_REF_NAME == "ci-deployment"
when: never
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'