Skip to content

Commit

Permalink
ci: Auto-generate changelog for API changes
Browse files Browse the repository at this point in the history
  • Loading branch information
MoritzWeber0 committed Oct 10, 2024
1 parent 40624ce commit ce13135
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 84 deletions.
44 changes: 0 additions & 44 deletions .github/workflows/openapi-frontend.yml

This file was deleted.

90 changes: 90 additions & 0 deletions .github/workflows/openapi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
# SPDX-License-Identifier: CC0-1.0

name: 'OpenAPI frontend client'

on:
pull_request:
branches: [main]

jobs:
generate-frontend-client:
runs-on: ubuntu-latest
if: github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@v4
- name: Install python
uses: actions/setup-python@v5
with:
cache: pip
cache-dependency-path: ./backend/pyproject.toml
python-version: '3.11'
- name: Install dependencies
working-directory: ./backend
run: python -m venv .venv && .venv/bin/pip install -e ".[dev]"
- name: Run openapi-generator
run: make openapi
- name: Compare against HEAD
id: git-diff
run: git add . && git diff --cached --exit-code
- name: Post comment if client is outdated
if: always() && steps.git-diff.outcome == 'failure'
uses: actions/github-script@v7
env:
TEXT: |-
The generated OpenAPI client is not up to date with the latest changes in the OpenAPI specification.
Please run `make openapi` locally and commit the changes.
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: process.env.TEXT
})
changelog:
runs-on: ubuntu-latest
if: github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@v4
- name: Install python
uses: actions/setup-python@v5
with:
cache: pip
cache-dependency-path: ./backend/pyproject.toml
python-version: '3.11'
- name: Install dependencies
working-directory: ./backend
run: python -m venv .venv && .venv/bin/pip install -e ".[dev]"
- name: Run openapi-generator for target
working-directory: ./backend
run: make openapi
- name: Move openapi schema file
run: mv /tmp/openapi.json /tmp/openapi2.json
- name: Checkout base
run: git checkout "${{ github.event.pull_request.base.sha }}"
- name: Run openapi-generator for base
working-directory: ./backend
run: make openapi
- name: Install oasdiff
run: go install github.com/tufin/oasdiff@latest
- name: Compare openapi schema files
id: oasdiff
run: |
{
echo 'changelog<<EOF'
oasdiff changelog \
--format markup \
/tmp/openapi.json /tmp/openapi2.json
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Post comment with changelog
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: "${{ steps.oasdiff.outputs.changelog }}"
})
7 changes: 6 additions & 1 deletion backend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ install:
$(VENV)/bin/pip install -e ".[dev]"

openapi:
CAPELLACOLLAB_SKIP_OPENAPI_ERROR_RESPONSES=1 $(VENV)/bin/python -m capellacollab.cli openapi generate /tmp/openapi.json
$(VENV)/bin/python \
-m capellacollab.cli openapi generate \
--remove-default-keys \
--remove-min-max-keys \
--skip-error-responses \
/tmp/openapi.json

dev: database valkey app

Expand Down
53 changes: 52 additions & 1 deletion backend/capellacollab/cli/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@

from __future__ import annotations

import copy
import json
import os
import pathlib
import typing as t

import typer

Expand All @@ -14,10 +17,58 @@
@app.command()
def generate(
output_file: pathlib.Path,
# For client generation, default keys might blow up the generated code.
remove_default_keys: bool = typer.Option(
default=False,
help=(
"Remove default keys from the schema."
" This might be useful for client generation to reduce verbosity of the generated code."
),
),
# Reason for this option is: https://github.com/fastapi/fastapi/issues/240
remove_min_max_keys: bool = typer.Option(
default=False,
help=(
"Remove the exclusiveMinimum and exclusiveMaximum keys from the schema."
" This improves compatibility with OpenAPI Spec 3.0."
),
),
skip_error_responses: bool = typer.Option(
default=False,
help=(
"Skip generation of error responses."
" This might be useful for client generation to reduce verbosity of the generated code."
),
),
):
"""Generate openapi.json and write it to output_file."""

if skip_error_responses:
os.environ["CAPELLACOLLAB_SKIP_OPENAPI_ERROR_RESPONSES"] = "1"

from capellacollab import __main__

keys_to_remove = []

if remove_default_keys:
keys_to_remove.append("default")

if remove_min_max_keys:
keys_to_remove.extend(["exclusiveMinimum", "exclusiveMaximum"])

schema = __main__.app.openapi()
_remove_keys_from_spec(schema, keys_to_remove)
with output_file.open("w") as f:
json.dump(__main__.app.openapi(), f)
json.dump(schema, f)


def _remove_keys_from_spec(value: t.Any, keys_to_remove: list[str]):
if isinstance(value, dict):
for k in copy.deepcopy(value):
if k in keys_to_remove:
del value[k]
else:
_remove_keys_from_spec(value[k], keys_to_remove)
elif isinstance(value, list):
for i in value:
_remove_keys_from_spec(i, keys_to_remove)
6 changes: 1 addition & 5 deletions backend/capellacollab/core/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,7 @@ def api_exceptions(
projects_users_models.ProjectUserPermission | None
) = None,
):
if os.getenv("CAPELLACOLLAB_SKIP_OPENAPI_ERROR_RESPONSES", "").lower() in (
"1",
"true",
"t",
):
if os.getenv("CAPELLACOLLAB_SKIP_OPENAPI_ERROR_RESPONSES", "0") == "1":
return {}

if excs is None:
Expand Down
1 change: 0 additions & 1 deletion frontend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ snapshots:
npx storycap http://localhost:6006 --serverCmd "npm run storybook" --flat

openapi:
python postprocess_openapi_schema.py
OPENAPI_DIR=$$(mktemp -d)
docker run --rm \
-v /tmp/openapi.json:/tmp/openapi.json \
Expand Down
32 changes: 0 additions & 32 deletions frontend/postprocess_openapi_schema.py

This file was deleted.

0 comments on commit ce13135

Please sign in to comment.