Skip to content

Commit feca208

Browse files
authored
Bugfix/490 artifacts validate fails for newly created project (#493)
* Add .gitattributes to project-template and update .gitignore * Adapt pyproject.toml to be the same * Define noxconfig values as iterable & set defaults with immutable type tuple to reduce warnings * Refactor in preparation of additional testing * Add tests for nox tasks that affect starting off a project * Add lint:code test for project-template & modify version.py to pass linting * Add test for artifacts:validate * Fix artifacts:validate and sonar:check to pass when working with newly created project * Remove and fix typings * Remove unneeded import * Fix typing for python 3.9 * Add coverage for prepare_coverage_xml * Fix hint for version.py * Remove assert of mock * Ignore warning on import for subprocess * Fix gitattributes * Elaborate on comment regarding coverage XML * Update comment with improved formatting using dashes * Add sub-types to noxconfig.py * Remove non-ASCII Unicodes in issue templates * Update comment to be less vague * Switch from is_file to exists * Test out what happens to sonarqubebot if no coverage included in pysonar upload * Finalize how we will handle no coverage for new projects in the PTB * Switch COVERAGE_FILE to COVERAGE_DB * Fix formatting issue in doc * Fix cwd which differs between the tests & real running * Fix type again; think it's a given , = | in my brain
1 parent 87a1cc9 commit feca208

File tree

24 files changed

+323
-283
lines changed

24 files changed

+323
-283
lines changed

.gitattributes

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
poetry.lock linguist-generated=true
1+
poetry.lock linguist-generated=true
2+
exasol/toolbox/version.py linguist-generated=true

doc/changes/unreleased.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
## Bugfixes
44

5-
* #489: Fixed .pre-commit-config.yaml to use existing nox tasks
5+
* #489: Fixed .pre-commit-config.yaml to use existing nox tasks
6+
* #490: Fixed artifacts:validate & sonar:check to work for newly created projects
7+
* #484: Fixed hint command text in version.py to include -s for executing nox task

doc/user_guide/getting_started.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,14 @@ We also need to configure settings for github-pages environment:
204204
8. Set up for Sonar
205205
+++++++++++++++++++
206206
PTB supports using SonarQube Cloud to analyze, visualize, & track linting, security, &
207-
coverage. In order to set it up, you'll need to do the following instructions.
207+
coverage. All of our Python projects are evaluated against the
208+
`Exasol Way <https://sonarcloud.io/organizations/exasol/quality_gates/show/AXxvLH-3BdtLlpiYmZhh>`__
209+
and subscribe to the
210+
`Clean as You Code <https://docs.sonarsource.com/sonarqube-server/9.8/user-guide/clean-as-you-code/>`__
211+
methodology, which means that SonarQube analysis will fail and, if its included in the branch protections, block a PR
212+
if code modified in that PR does not meet the standards of the Exasol Way.
213+
214+
In order to set up Sonar, you will need to perform the following instructions.
208215

209216
For a **public** project
210217
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -224,6 +231,12 @@ For a **public** project
224231
organization = "exasol"
225232
6. Post-merge, update the branch protections to include SonarQube analysis
226233

234+
* This should only be done when tests exist for the project, & that the project is
235+
at a state in which enforced code coverage would not be a burden. For new projects,
236+
we recommend creating an issue to add the SonarQube analysis to the branch protections
237+
at a later point. In such scenarios, SonarQube analysis will still report its analysis
238+
results to the PR, but it will not prevent the PR from being merged.
239+
227240
For a **private** project
228241
^^^^^^^^^^^^^^^^^^^^^^^^^
229242
1. Specify in the `noxconfig.py` the relative path to the project's source code in `Config.source`

exasol/toolbox/nox/_artifacts.py

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
import re
44
import shutil
55
import sqlite3
6+
import subprocess # nosec
67
import sys
78
from collections.abc import Iterable
89
from pathlib import Path
9-
from typing import Optional
10+
from typing import (
11+
Optional,
12+
Union,
13+
)
1014

1115
import nox
1216
from nox import Session
@@ -17,13 +21,13 @@
1721
Config,
1822
)
1923

20-
COVERAGE_FILE = ".coverage"
24+
COVERAGE_DB = ".coverage"
2125
COVERAGE_XML = "ci-coverage.xml"
2226
LINT_JSON = ".lint.json"
2327
LINT_TXT = ".lint.txt"
2428
SECURITY_JSON = ".security.json"
2529

26-
ALL_LINT_FILES = {COVERAGE_FILE, LINT_JSON, LINT_TXT, SECURITY_JSON}
30+
ALL_LINT_FILES = {COVERAGE_DB, LINT_JSON, LINT_TXT, SECURITY_JSON}
2731
COVERAGE_TABLES = {"coverage_schema", "meta", "file", "line_bits"}
2832
LINT_JSON_ATTRIBUTES = {
2933
"type",
@@ -54,7 +58,7 @@ def check_artifacts(session: Session) -> None:
5458
_is_valid_lint_txt(Path(PROJECT_CONFIG.root, LINT_TXT)),
5559
_is_valid_lint_json(Path(PROJECT_CONFIG.root, LINT_JSON)),
5660
_is_valid_security_json(Path(PROJECT_CONFIG.root, SECURITY_JSON)),
57-
_is_valid_coverage(Path(PROJECT_CONFIG.root, COVERAGE_FILE)),
61+
_is_valid_coverage(Path(PROJECT_CONFIG.root, COVERAGE_DB)),
5862
]
5963
if not all(all_is_valid_checks):
6064
sys.exit(1)
@@ -145,7 +149,7 @@ def copy_artifacts(session: Session) -> None:
145149

146150
artifact_dir = Path(session.posargs[0])
147151
suffix = _python_version_suffix()
148-
_combine_coverage(session, artifact_dir, f"coverage{suffix}*/{COVERAGE_FILE}")
152+
_combine_coverage(session, artifact_dir, f"coverage{suffix}*/{COVERAGE_DB}")
149153
_copy_artifacts(
150154
artifact_dir,
151155
artifact_dir.parent,
@@ -183,9 +187,45 @@ def _copy_artifacts(source: Path, dest: Path, files: Iterable[str]):
183187
print(f"File not found {path}", file=sys.stderr)
184188

185189

186-
def _prepare_coverage_xml(session: Session, source: Path) -> None:
187-
command = ["coverage", "xml", "-o", COVERAGE_XML, "--include", f"{source}/*"]
188-
session.run(*command)
190+
def _prepare_coverage_xml(
191+
session: Session, source: Path, cwd: Union[Path, None] = None
192+
) -> None:
193+
"""
194+
Prepare the coverage XML for input into Sonar
195+
196+
The coverage XML is used within Sonar to determine the overall coverage in our
197+
project and the coverage associated with source code changes made in a PR. If the
198+
code coverage associated with changes made in our PR does not meet the set Sonar
199+
guidelines for that project, then when the sonarqubecloud bot writes in the PR, it
200+
will indicate that the coverage constraint was not met, &, if the bot is required in
201+
the branch protections for that project, then it will block the PR from being
202+
merged. Thus, in the preparation of the coverage XML, we set `--fail-under=0` so
203+
that this sub-step will not fail prior to sending the data to Sonar. Otherwise, this
204+
sub-step would fail whenever the `fail_under` in `[tool.coverage.report]` of the
205+
`pyproject.toml` was not met.
206+
"""
207+
command = [
208+
"coverage",
209+
"xml",
210+
"-o",
211+
COVERAGE_XML,
212+
"--include",
213+
f"{source}/*",
214+
"--fail-under=0",
215+
]
216+
output = subprocess.run(command, capture_output=True, text=True, cwd=cwd) # nosec
217+
if output.returncode != 0:
218+
if output.stdout.strip() == "No data to report.":
219+
# Assuming that previous steps passed in the CI, this indicates — as
220+
# is in the case for newly created projects — that no coverage over the
221+
# `source` files was found. In this scenario, we do not need the CI to
222+
# break from a non-zero exit code. This is because without a coverage file
223+
# the sonarqubecloud bot will still report that the coverage is 0%, but as
224+
# long as the bot is not required in the project's branch protections, then
225+
# the PR can still be merged, provided that the other required constraints
226+
# have been met.
227+
return
228+
session.error(output.returncode, output.stdout, output.stderr)
189229

190230

191231
def _upload_to_sonar(
@@ -195,8 +235,6 @@ def _upload_to_sonar(
195235
"pysonar",
196236
"--sonar-token",
197237
sonar_token,
198-
"--sonar-python-coverage-report-paths",
199-
COVERAGE_XML,
200238
"--sonar-python-pylint-report-path",
201239
LINT_JSON,
202240
"--sonar-python-bandit-report-paths",
@@ -206,6 +244,8 @@ def _upload_to_sonar(
206244
"--sonar-sources",
207245
config.source,
208246
]
247+
if Path(COVERAGE_XML).exists():
248+
command.extend(["--sonar-python-coverage-report-paths", COVERAGE_XML])
209249
session.run(*command) # type: ignore
210250

211251

exasol/toolbox/nox/_package_version.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020

2121
# fmt: off
2222
_VERSION_MODULE_TEMPLATE = cleandoc('''
23-
# ATTENTION:
24-
# This file is generated by exasol/toolbox/nox/_package_version.py when using:
25-
# * either "poetry run -- nox -s project:fix"
26-
# * or "poetry run -- nox version:check -- --fix"
27-
# Do not edit this file manually!
28-
# If you need to change the version, do so in the pyproject.toml, e.g. by using `poetry version X.Y.Z`.
23+
""" ATTENTION:
24+
This file is generated by exasol/toolbox/nox/_package_version.py when using:
25+
* either "poetry run -- nox -s project:fix"
26+
* or "poetry run -- nox -s version:check -- --fix"
27+
Do not edit this file manually!
28+
If you need to change the version, do so in the pyproject.toml, e.g. by using
29+
`poetry version X.Y.Z`.
30+
"""
2931
MAJOR = {major}
3032
MINOR = {minor}
3133
PATCH = {patch}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
2-
name: 📝 Blank Issue
2+
name: Blank Issue
33
about: Blank Issue
4-
title: 📝 <Insert Title>
5-
labels:
4+
title: <Insert Title>
5+
labels:
66
assignees: ''
77

88
---

exasol/toolbox/templates/github/ISSUE_TEMPLATE/bug.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
name: 🐞 Bug Report
2+
name: Bug Report
33
about: File a bug report
4-
title: 🐞 <Insert Title>
4+
title: <Insert Title>
55
labels: bug
66
assignees: ''
77

@@ -74,4 +74,4 @@ Add any additional context about the problem here.
7474
#### Related Issues (optional)
7575
<!---
7676
Link related issues form the issue tracker here.
77-
-->
77+
-->

exasol/toolbox/templates/github/ISSUE_TEMPLATE/documentation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
name: 📚 Documentation
2+
name: Documentation
33
about: Add/Improve Documentation
4-
title: 📚 <Insert Title>
4+
title: <Insert Title>
55
labels: documentation
66
assignees: ''
77

@@ -38,4 +38,4 @@ e.g.:
3838
- [ ] Bump version number
3939
- [ ] Update changelog
4040
- [ ] ...
41-
--->
41+
--->

exasol/toolbox/templates/github/ISSUE_TEMPLATE/feature.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
name: Feature
2+
name: Feature
33
about: Add/Implement Feature
4-
title: <Insert Title>
4+
title: <Insert Title>
55
labels: feature
66
assignees: ''
77

@@ -44,4 +44,4 @@ e.g.:
4444
- [ ] Update documentation
4545
- [ ] Update changelog
4646
- [ ] ...
47-
--->
47+
--->

exasol/toolbox/templates/github/ISSUE_TEMPLATE/refactoring.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
name: 🔧 Refactoring
2+
name: Refactoring
33
about: Refactor
4-
title: 🔧 <Insert Title>
4+
title: <Insert Title>
55
labels: refactoring
66
assignees: ''
77

@@ -44,4 +44,4 @@ e.g.:
4444
- [ ] Bump version number
4545
- [ ] Update changelog
4646
- [ ] ...
47-
--->
47+
--->

0 commit comments

Comments
 (0)