Skip to content

Commit

Permalink
feat(action): add build test and sonarcloud
Browse files Browse the repository at this point in the history
Signed-off-by: Vincent Koppen <[email protected]>
  • Loading branch information
vincentkoppen committed Jan 17, 2025
1 parent cc05734 commit a60b448
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 1 deletion.
173 changes: 173 additions & 0 deletions .github/workflows/build-test-and-sonar.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
#
# SPDX-License-Identifier: MPL-2.0


name: Build, Test, Sonar and Publish

on:
push:
branches:
- main
- feature/github_actions
# run pipeline on pull request
pull_request:
# run pipeline on merge queue
merge_group:
# run pipeline from another workflow
workflow_call:
inputs:
create_release:
type: boolean
description: Create a (pre-)release when CI passes
default: false
required: false
# run this workflow manually from the Actions tab
workflow_dispatch:
inputs:
create_release:
type: boolean
description: Create a (pre-)release when CI passes
default: false
required: true

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-main
cancel-in-progress: true

jobs:

build-python:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:

- name: Checkout source code
uses: actions/checkout@v4

- name: Setup Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Build
run: |
pip install requests build
python set_pypi_version.py
python -m build --outdir wheelhouse .
- name: Save version
id: version
run: echo "version=$(cat PYPI_VERSION)" >> $GITHUB_OUTPUT

- name: Store built wheel file
uses: actions/upload-artifact@v4
with:
name: power-grid-model-ds
path: wheelhouse/

sonar-cloud:
if: false #skip until open source
permissions:
contents: write
runs-on: ubuntu-latest
steps:

- name: Checkout source code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis

- name: Setup Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install in develop mode
run: |
pip install -e .[dev]
- name: Test and Coverage
run: |
coverage run -m pytest
coverage xml
coverage report --fail-under=80
- name: SonarCloud Scan
if: ${{ (github.event_name == 'push') || (github.event.pull_request.head.repo.owner.login == 'PowerGridModel') }}
uses: SonarSource/sonarqube-scan-action@v4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

tests:
needs: build-python
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python: ["3.10", "3.11", "3.12", "3.13"]
fail-fast: false
runs-on: ${{ matrix.os }}

steps:
- name: Checkout source code
uses: actions/checkout@v4

- name: Setup Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}

- name: Load built wheel file
uses: actions/download-artifact@v4
with:
name: power-grid-model-ds
path: wheelhouse/

- name: Install built wheel file
run: pip install power-grid-model-ds[dev]==${{ needs.build-python.outputs.version }} --find-links=wheelhouse

- name: Unit test and coverage
run: pytest --verbose

publish:
needs:
- build-python
- tests
- sonar-cloud
permissions:
contents: write
env:
TWINE_USERNAME: ${{ secrets.PYPI_USER }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASS }}
runs-on: ubuntu-latest
steps:
- name: Setup Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Load built wheel file
uses: actions/download-artifact@v4
with:
name: power-grid-model-ds
path: wheelhouse/

# - name: Upload wheels
# if: (github.event_name == 'push') || ((github.event_name == 'workflow_dispatch') && (github.event.inputs.create_release == 'true'))
# run: |
# pip install twine
# echo "Publish to PyPI..."
# twine upload --verbose wheelhouse/*

# - name: Release
# if: (github.event_name == 'push') || ((github.event_name == 'workflow_dispatch') && (github.event.inputs.create_release == 'true'))
# uses: softprops/action-gh-release@v2
# with:
# files: |
# ./wheelhouse/*
# tag_name: v${{ needs.build-python.outputs.version }}
# prerelease: ${{github.ref != 'refs/heads/main'}}
# generate_release_notes: true
# target_commitish: ${{ github.sha }}
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.1
0.0
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,7 @@ unfixable = []

[tool.mypy]
disable_error_code = ["assignment", "import-untyped"]

[tool.coverage.run]
relative_files = true
branch = true
70 changes: 70 additions & 0 deletions set_pypi_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
#
# SPDX-License-Identifier: MPL-2.0

# script to set version dynamically
# read VERSION and PyPI, set PYPI_VERSION


import os
from pathlib import Path

import requests


def set_version(pkg_dir: Path):
with open(pkg_dir / "VERSION") as f:
version = f.read().strip().strip("\n")
major, minor = (int(x) for x in version.split("."))
latest_major, latest_minor, latest_patch = get_pypi_latest()
# get version
version = get_new_version(major, minor, latest_major, latest_minor, latest_patch)
# mutate version in GitHub Actions
if ("GITHUB_SHA" in os.environ) and ("GITHUB_REF" in os.environ) and ("GITHUB_RUN_NUMBER" in os.environ):
sha = os.environ["GITHUB_SHA"]
ref = os.environ["GITHUB_REF"]
build_number = os.environ["GITHUB_RUN_NUMBER"]
# short hash number in numeric
short_hash = f"{int(f'0x{sha[0:6]}', base=16):08}"

if "main" in ref:
# main branch
# major.minor.patch
# do nothing
pass
else:
# feature branch
# major.minor.patch a 1 build_number short_hash
version += f"a1{build_number}{short_hash}"
with open(pkg_dir / "PYPI_VERSION", "w") as f:
f.write(version)


def get_pypi_latest():
response = requests.get("https://pypi.org/pypi/power-grid-model-ds/json")
if response.status_code == 404:
return 0, 0, 0
data = response.json()
version = str(data["info"]["version"])
return (int(x) for x in version.split("."))


def get_new_version(major, minor, latest_major, latest_minor, latest_patch):
if (major > latest_major) or ((major == latest_major) and minor > latest_minor):
# brand-new version with patch zero
return f"{major}.{minor}.0"

if major == latest_major and minor == latest_minor:
# current version, increment path
return f"{major}.{minor}.{latest_patch + 1}"

# does not allow building older version
raise ValueError(
"Invalid version number!\n"
f"latest version: {latest_major}.{latest_minor}.{latest_patch}\n"
f"to be built version: {major}.{minor}\n"
)


if __name__ == "__main__":
set_version(Path(__file__).parent)

0 comments on commit a60b448

Please sign in to comment.