name: CI
on:
merge_group:
push:
tags:
- '*'
branches-ignore:
- 'gh-readonly-queue/**'
- 'dependabot/**'
workflow_dispatch:
env:
DEFAULT_PYTHON_VERSION: '3.11'
jobs:
protolint:
name: Check proto files with protolint
runs-on: ubuntu-24.04
steps:
- name: Setup Git
uses: frequenz-floss/gh-action-setup-git@v1.0.0
- name: Fetch sources
uses: actions/checkout@v4
with:
submodules: true
- name: Run protolint
uses: yoheimuta/action-protolint@e62319541dc5107df5e3a5010acb8987004d3d25 with:
fail_on_error: true
filter_mode: nofilter
github_token: ${{ secrets.github_token }}
protolint_flags: proto/
protolint_version: "0.53.0"
reporter: github-check
protoc:
name: Test with protoc
runs-on: ubuntu-24.04
steps:
- name: Fetch sources
uses: actions/checkout@v4
with:
submodules: true
- name: Source protoc
run: |
curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v25.1/protoc-25.1-linux-x86_64.zip
mkdir protoc
unzip protoc-25.1-linux-x86_64.zip -d protoc
sudo cp -r protoc/bin/* /usr/bin/
sudo cp -r protoc/include/* /usr/include/
rm -r protoc-25.1-linux-x86_64.zip protoc
- name: Run sanity tests
run: |
protoc \
--fatal_warnings \
-I proto \
-I submodules/frequenz-api-common/proto \
-I submodules/api-common-protos \
--python_out=. \
frequenz/api/microgrid/v1/microgrid.proto
nox:
name: Test with nox
strategy:
fail-fast: false
matrix:
arch:
- amd64
- arm
os:
- ubuntu-24.04
python:
- "3.11"
- "3.12"
nox-session:
- "ci_checks_max"
- "pytest_min"
runs-on: ${{ matrix.os }}${{ matrix.arch != 'amd64' && format('-{0}', matrix.arch) || '' }}
steps:
- name: Run nox
uses: frequenz-floss/gh-action-nox@v1.0.0
with:
python-version: ${{ matrix.python }}
nox-session: ${{ matrix.nox-session }}
nox-all:
name: Test with nox
needs: ["nox"]
if: always() && needs.nox.result != 'skipped'
runs-on: ubuntu-24.04
env:
DEPS_RESULT: ${{ needs.nox.result }}
steps:
- name: Check matrix job result
run: test "$DEPS_RESULT" = "success"
build:
name: Build distribution packages
runs-on: ubuntu-24.04
steps:
- name: Setup Git
uses: frequenz-floss/gh-action-setup-git@v1.0.0
- name: Fetch sources
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Python
uses: frequenz-floss/gh-action-setup-python-with-deps@v1.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
dependencies: build
- name: Build the source and binary distribution
run: python -m build
- name: Upload distribution files
uses: actions/upload-artifact@v4
with:
name: dist-packages
path: dist/
if-no-files-found: error
test-installation:
name: Test package installation
needs: ["build"]
strategy:
fail-fast: false
matrix:
arch:
- amd64
- arm
os:
- ubuntu-24.04
python:
- "3.11"
- "3.12"
runs-on: ${{ matrix.os }}${{ matrix.arch != 'amd64' && format('-{0}', matrix.arch) || '' }}
steps:
- name: Setup Git
uses: frequenz-floss/gh-action-setup-git@v1.0.0
- name: Print environment (debug)
run: env
- name: Download package
uses: actions/download-artifact@v4
with:
name: dist-packages
path: dist
- name: Fetch the pyproject.toml file for this action hash
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
REF: ${{ github.sha }}
run: |
set -ux
gh api \
-X GET \
-H "Accept: application/vnd.github.raw" \
"/repos/$REPO/contents/pyproject.toml?ref=$REF" \
> pyproject.toml
- name: Setup Python
uses: frequenz-floss/gh-action-setup-python-with-deps@v1.0.0
with:
python-version: ${{ matrix.python }}
dependencies: dist/*.whl
- name: Print installed packages (debug)
run: python -m pip freeze
test-installation-all:
name: Test package installation
needs: ["test-installation"]
if: always() && needs.test-installation.result != 'skipped'
runs-on: ubuntu-24.04
env:
DEPS_RESULT: ${{ needs.test-installation.result }}
steps:
- name: Check matrix job result
run: test "$DEPS_RESULT" = "success"
test-docs:
name: Test documentation website generation
if: github.event_name != 'push'
runs-on: ubuntu-24.04
steps:
- name: Setup Git
uses: frequenz-floss/gh-action-setup-git@v1.0.0
- name: Fetch sources
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Python
uses: frequenz-floss/gh-action-setup-python-with-deps@v1.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
dependencies: .[dev-mkdocs]
- name: Generate the documentation
env:
MIKE_VERSION: gh-${{ github.job }}
run: |
mike deploy $MIKE_VERSION
mike set-default $MIKE_VERSION
- name: Upload site
uses: actions/upload-artifact@v4
with:
name: docs-site
path: site/
if-no-files-found: error
publish-docs:
name: Publish documentation website to GitHub pages
needs: ["nox-all", "test-installation-all"]
if: github.event_name == 'push'
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- name: Setup Git
uses: frequenz-floss/gh-action-setup-git@v1.0.0
- name: Fetch sources
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Python
uses: frequenz-floss/gh-action-setup-python-with-deps@v1.0.0
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
dependencies: .[dev-mkdocs]
- name: Calculate and check version
id: mike-version
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPO: ${{ github.repository }}
GIT_REF: ${{ github.ref }}
GIT_SHA: ${{ github.sha }}
run: |
python -m frequenz.repo.config.cli.version.mike.info
- name: Fetch the gh-pages branch
if: steps.mike-version.outputs.version
run: git fetch origin gh-pages --depth=1
- name: Build site
if: steps.mike-version.outputs.version
env:
VERSION: ${{ steps.mike-version.outputs.version }}
TITLE: ${{ steps.mike-version.outputs.title }}
ALIASES: ${{ steps.mike-version.outputs.aliases }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPO: ${{ github.repository }}
GIT_REF: ${{ github.ref }}
GIT_SHA: ${{ github.sha }}
run: |
mike deploy --update-aliases --title "$TITLE" "$VERSION" $ALIASES
- name: Sort site versions
if: steps.mike-version.outputs.version
run: |
git checkout gh-pages
python -m frequenz.repo.config.cli.version.mike.sort versions.json
git commit -a -m "Sort versions.json"
- name: Publish site
if: steps.mike-version.outputs.version
run: |
git push origin gh-pages
create-github-release:
name: Create GitHub release
needs: ["publish-docs"]
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
discussions: write
runs-on: ubuntu-24.04
steps:
- name: Download distribution files
uses: actions/download-artifact@v4
with:
name: dist-packages
path: dist
- name: Download RELEASE_NOTES.md
run: |
set -ux
gh api \
-X GET \
-f ref=$REF \
-H "Accept: application/vnd.github.raw" \
"/repos/$REPOSITORY/contents/RELEASE_NOTES.md" \
> RELEASE_NOTES.md
env:
REF: ${{ github.ref }}
REPOSITORY: ${{ github.repository }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub release
run: |
set -ux
extra_opts=
if echo "$REF_NAME" | grep -- -; then extra_opts=" --prerelease"; fi
gh release create \
-R "$REPOSITORY" \
--notes-file RELEASE_NOTES.md \
--generate-notes \
$extra_opts \
$REF_NAME \
dist/*
env:
REF_NAME: ${{ github.ref_name }}
REPOSITORY: ${{ github.repository }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-to-pypi:
name: Publish packages to PyPI
needs: ["create-github-release"]
runs-on: ubuntu-24.04
permissions:
id-token: write
steps:
- name: Download distribution files
uses: actions/download-artifact@v4
with:
name: dist-packages
path: dist
- name: Publish the Python distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1