Skip to content

Commit 8c62c22

Browse files
committed
feat: add common workflow for python libraries
Refs: KEH-282
1 parent 3223075 commit 8c62c22

2 files changed

Lines changed: 166 additions & 0 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Reusable CI workflow for Python libraries
2+
3+
This reusable workflow is part of the City of Helsinki's GitHub Actions setup, specifically designed to provide an opinionated and consistent CI process for City of Helsinki's Python library projects.
4+
5+
## Key Features
6+
7+
- **Commit Linting**: Enforces commit message standards using [commitlint](https://commitlint.js.org/).
8+
- **Code Style Checks**: Verifies code style and formatting using [pre-commit](https://pre-commit.com/).
9+
- **Automated Testing**: Runs project tests across multiple Python versions using [hatch](https://hatch.pypa.io/).
10+
- **Code Quality Analysis**: Performs a [SonarQube Cloud](https://sonarcloud.io/) scan.
11+
12+
## Requirements for Projects Using the Workflow
13+
14+
- **commitlint** [config file](https://commitlint.js.org/reference/configuration.html#config-via-file) is present in the root of the project.
15+
- **pre-commit** is set up with a `.pre-commit-config.yaml` file in the root of the project.
16+
- **hatch** is used for testing, with a `pyproject.toml` that defines the test environments.
17+
- **SonarQube Cloud** is configured with `SONAR_TOKEN` set in the repository secrets.
18+
19+
## Usage Instructions
20+
21+
To use this reusable workflow, create a project-specific workflow file in your `.github/workflows` directory. Set the `uses` value to `City-of-Helsinki/.github/.github/workflows/ci-python-library.yml@main`, set `secrets: inherit`, and provide the following inputs as needed:
22+
23+
### Required Inputs
24+
25+
- **`python-matrix`** (string): Python versions to use in the test matrix. Must be an array inside a string, e.g. `"['3.12', '3.13']"`.
26+
27+
### Optional Inputs
28+
29+
- **`python-version`** (string): Python version to use for pre-commit checks. Defaults to `"3.x"`.
30+
- **`enable-sonar`** (boolean): Whether to run the SonarQube Cloud Scan job after tests. Defaults to `true`.
31+
32+
### Example usage (`<own project>/.github/workflows/ci.yml`)
33+
34+
```yaml
35+
name: CI
36+
37+
on:
38+
push:
39+
branches: [main]
40+
pull_request:
41+
branches: [main]
42+
workflow_dispatch:
43+
44+
concurrency:
45+
group: ${{ github.workflow }}-${{ github.ref }}
46+
cancel-in-progress: true
47+
48+
jobs:
49+
common:
50+
uses: City-of-Helsinki/.github/.github/workflows/ci-python-library.yml@main
51+
secrets: inherit
52+
with:
53+
python-matrix: "['3.10', '3.11', '3.12', '3.13', '3.14']"
54+
```
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: Common CI for Python libraries
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
python-matrix:
7+
description: "Python versions to use in the test matrix. This needs to be an array inside of a string, e.g. \"['3.10', '3.11']\", due to GHA not supporting array inputs."
8+
required: true
9+
type: string
10+
python-version:
11+
description: "Python version to use for pre-commit checks."
12+
required: false
13+
type: string
14+
default: "3.x"
15+
enable-sonar:
16+
description: "Whether to run the SonarQube Cloud Scan job after tests or not. Enabled by default."
17+
required: false
18+
type: boolean
19+
default: true
20+
21+
jobs:
22+
commitlint:
23+
name: Check commit messages
24+
runs-on: ubuntu-latest
25+
26+
steps:
27+
- name: Checkout
28+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
29+
30+
- name: Run commitlint
31+
uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6.2.1
32+
33+
pre-commit:
34+
name: Run pre-commit hooks
35+
runs-on: ubuntu-latest
36+
steps:
37+
- name: Checkout
38+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
39+
40+
- name: Setup Python ${{ inputs.python-version }}
41+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
42+
with:
43+
python-version: ${{ inputs.python-version }}
44+
45+
- name: Run pre-commit
46+
uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
47+
48+
tests:
49+
name: Python ${{ matrix.python_version }}
50+
runs-on: ubuntu-latest
51+
strategy:
52+
matrix:
53+
python_version: ${{ fromJSON(inputs.python-matrix) }}
54+
55+
steps:
56+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
57+
58+
- name: Set up Python ${{ matrix.python_version }}
59+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
60+
with:
61+
python-version: ${{ matrix.python_version }}
62+
63+
- name: Set up pip cache
64+
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
65+
env:
66+
cache-name: cache-pip-modules
67+
with:
68+
path: ~/.cache/pip
69+
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('pyproject.toml') }}
70+
restore-keys: |
71+
${{ runner.os }}-build-${{ env.cache-name }}-
72+
${{ runner.os }}-build-
73+
${{ runner.os }}-
74+
75+
- name: Install hatch
76+
run: python -m pip install hatch
77+
78+
- name: Run tests
79+
run: hatch test -c -i py=${{ matrix.python_version }}
80+
81+
- name: Generate coverage report
82+
run: hatch run coverage xml -o coverage-${{ matrix.python_version }}.xml
83+
84+
- name: Upload coverage report
85+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
86+
with:
87+
name: coverage-${{ matrix.python_version }}
88+
path: coverage-${{ matrix.python_version }}.xml
89+
90+
sonarcloud:
91+
name: Run SonarQube Cloud Scan
92+
runs-on: ubuntu-latest
93+
needs: tests
94+
if: ${{ inputs.enable-sonar }}
95+
96+
steps:
97+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
98+
with:
99+
# Required by SonarQube Cloud
100+
fetch-depth: 0
101+
102+
- name: Download coverage reports
103+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
104+
with:
105+
merge-multiple: true
106+
path: .coverage-reports
107+
108+
- name: SonarQube Cloud Scan
109+
uses: SonarSource/sonarqube-scan-action@fd88b7d7ccbaefd23d8f36f73b59db7a3d246602 # v6.0.0
110+
env:
111+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
112+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

0 commit comments

Comments
 (0)