Skip to content

Commit a60b448

Browse files
committed
feat(action): add build test and sonarcloud
Signed-off-by: Vincent Koppen <[email protected]>
1 parent cc05734 commit a60b448

File tree

4 files changed

+248
-1
lines changed

4 files changed

+248
-1
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
2+
#
3+
# SPDX-License-Identifier: MPL-2.0
4+
5+
6+
name: Build, Test, Sonar and Publish
7+
8+
on:
9+
push:
10+
branches:
11+
- main
12+
- feature/github_actions
13+
# run pipeline on pull request
14+
pull_request:
15+
# run pipeline on merge queue
16+
merge_group:
17+
# run pipeline from another workflow
18+
workflow_call:
19+
inputs:
20+
create_release:
21+
type: boolean
22+
description: Create a (pre-)release when CI passes
23+
default: false
24+
required: false
25+
# run this workflow manually from the Actions tab
26+
workflow_dispatch:
27+
inputs:
28+
create_release:
29+
type: boolean
30+
description: Create a (pre-)release when CI passes
31+
default: false
32+
required: true
33+
34+
concurrency:
35+
group: ${{ github.workflow }}-${{ github.ref }}-main
36+
cancel-in-progress: true
37+
38+
jobs:
39+
40+
build-python:
41+
runs-on: ubuntu-latest
42+
outputs:
43+
version: ${{ steps.version.outputs.version }}
44+
steps:
45+
46+
- name: Checkout source code
47+
uses: actions/checkout@v4
48+
49+
- name: Setup Python 3.11
50+
uses: actions/setup-python@v5
51+
with:
52+
python-version: "3.11"
53+
54+
- name: Build
55+
run: |
56+
pip install requests build
57+
python set_pypi_version.py
58+
python -m build --outdir wheelhouse .
59+
60+
- name: Save version
61+
id: version
62+
run: echo "version=$(cat PYPI_VERSION)" >> $GITHUB_OUTPUT
63+
64+
- name: Store built wheel file
65+
uses: actions/upload-artifact@v4
66+
with:
67+
name: power-grid-model-ds
68+
path: wheelhouse/
69+
70+
sonar-cloud:
71+
if: false #skip until open source
72+
permissions:
73+
contents: write
74+
runs-on: ubuntu-latest
75+
steps:
76+
77+
- name: Checkout source code
78+
uses: actions/checkout@v4
79+
with:
80+
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
81+
82+
- name: Setup Python 3.11
83+
uses: actions/setup-python@v5
84+
with:
85+
python-version: "3.11"
86+
87+
- name: Install in develop mode
88+
run: |
89+
pip install -e .[dev]
90+
91+
- name: Test and Coverage
92+
run: |
93+
coverage run -m pytest
94+
coverage xml
95+
coverage report --fail-under=80
96+
97+
- name: SonarCloud Scan
98+
if: ${{ (github.event_name == 'push') || (github.event.pull_request.head.repo.owner.login == 'PowerGridModel') }}
99+
uses: SonarSource/sonarqube-scan-action@v4
100+
env:
101+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
102+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
103+
104+
tests:
105+
needs: build-python
106+
strategy:
107+
matrix:
108+
os: [ubuntu-latest, macos-latest, windows-latest]
109+
python: ["3.10", "3.11", "3.12", "3.13"]
110+
fail-fast: false
111+
runs-on: ${{ matrix.os }}
112+
113+
steps:
114+
- name: Checkout source code
115+
uses: actions/checkout@v4
116+
117+
- name: Setup Python ${{ matrix.python }}
118+
uses: actions/setup-python@v5
119+
with:
120+
python-version: ${{ matrix.python }}
121+
122+
- name: Load built wheel file
123+
uses: actions/download-artifact@v4
124+
with:
125+
name: power-grid-model-ds
126+
path: wheelhouse/
127+
128+
- name: Install built wheel file
129+
run: pip install power-grid-model-ds[dev]==${{ needs.build-python.outputs.version }} --find-links=wheelhouse
130+
131+
- name: Unit test and coverage
132+
run: pytest --verbose
133+
134+
publish:
135+
needs:
136+
- build-python
137+
- tests
138+
- sonar-cloud
139+
permissions:
140+
contents: write
141+
env:
142+
TWINE_USERNAME: ${{ secrets.PYPI_USER }}
143+
TWINE_PASSWORD: ${{ secrets.PYPI_PASS }}
144+
runs-on: ubuntu-latest
145+
steps:
146+
- name: Setup Python 3.11
147+
uses: actions/setup-python@v5
148+
with:
149+
python-version: "3.11"
150+
151+
- name: Load built wheel file
152+
uses: actions/download-artifact@v4
153+
with:
154+
name: power-grid-model-ds
155+
path: wheelhouse/
156+
157+
# - name: Upload wheels
158+
# if: (github.event_name == 'push') || ((github.event_name == 'workflow_dispatch') && (github.event.inputs.create_release == 'true'))
159+
# run: |
160+
# pip install twine
161+
# echo "Publish to PyPI..."
162+
# twine upload --verbose wheelhouse/*
163+
164+
# - name: Release
165+
# if: (github.event_name == 'push') || ((github.event_name == 'workflow_dispatch') && (github.event.inputs.create_release == 'true'))
166+
# uses: softprops/action-gh-release@v2
167+
# with:
168+
# files: |
169+
# ./wheelhouse/*
170+
# tag_name: v${{ needs.build-python.outputs.version }}
171+
# prerelease: ${{github.ref != 'refs/heads/main'}}
172+
# generate_release_notes: true
173+
# target_commitish: ${{ github.sha }}

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.1
1+
0.0

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,7 @@ unfixable = []
104104

105105
[tool.mypy]
106106
disable_error_code = ["assignment", "import-untyped"]
107+
108+
[tool.coverage.run]
109+
relative_files = true
110+
branch = true

set_pypi_version.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
2+
#
3+
# SPDX-License-Identifier: MPL-2.0
4+
5+
# script to set version dynamically
6+
# read VERSION and PyPI, set PYPI_VERSION
7+
8+
9+
import os
10+
from pathlib import Path
11+
12+
import requests
13+
14+
15+
def set_version(pkg_dir: Path):
16+
with open(pkg_dir / "VERSION") as f:
17+
version = f.read().strip().strip("\n")
18+
major, minor = (int(x) for x in version.split("."))
19+
latest_major, latest_minor, latest_patch = get_pypi_latest()
20+
# get version
21+
version = get_new_version(major, minor, latest_major, latest_minor, latest_patch)
22+
# mutate version in GitHub Actions
23+
if ("GITHUB_SHA" in os.environ) and ("GITHUB_REF" in os.environ) and ("GITHUB_RUN_NUMBER" in os.environ):
24+
sha = os.environ["GITHUB_SHA"]
25+
ref = os.environ["GITHUB_REF"]
26+
build_number = os.environ["GITHUB_RUN_NUMBER"]
27+
# short hash number in numeric
28+
short_hash = f"{int(f'0x{sha[0:6]}', base=16):08}"
29+
30+
if "main" in ref:
31+
# main branch
32+
# major.minor.patch
33+
# do nothing
34+
pass
35+
else:
36+
# feature branch
37+
# major.minor.patch a 1 build_number short_hash
38+
version += f"a1{build_number}{short_hash}"
39+
with open(pkg_dir / "PYPI_VERSION", "w") as f:
40+
f.write(version)
41+
42+
43+
def get_pypi_latest():
44+
response = requests.get("https://pypi.org/pypi/power-grid-model-ds/json")
45+
if response.status_code == 404:
46+
return 0, 0, 0
47+
data = response.json()
48+
version = str(data["info"]["version"])
49+
return (int(x) for x in version.split("."))
50+
51+
52+
def get_new_version(major, minor, latest_major, latest_minor, latest_patch):
53+
if (major > latest_major) or ((major == latest_major) and minor > latest_minor):
54+
# brand-new version with patch zero
55+
return f"{major}.{minor}.0"
56+
57+
if major == latest_major and minor == latest_minor:
58+
# current version, increment path
59+
return f"{major}.{minor}.{latest_patch + 1}"
60+
61+
# does not allow building older version
62+
raise ValueError(
63+
"Invalid version number!\n"
64+
f"latest version: {latest_major}.{latest_minor}.{latest_patch}\n"
65+
f"to be built version: {major}.{minor}\n"
66+
)
67+
68+
69+
if __name__ == "__main__":
70+
set_version(Path(__file__).parent)

0 commit comments

Comments
 (0)