From 0c2f1cceb6ce4e3cac89e212c8160a2dfa9977a3 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Tue, 13 Feb 2024 01:57:25 +0000 Subject: [PATCH] Add API change detection (#6440) * Add basic task for generating apidocs * Fix SPECTACTULAR_SETTINGS - Some provided options were not correct * Update .gitignore * Fix for duplicated API path - `/api/plugins/activate` routed to PluginActivate view - Must be associated with a specific plugin ID * By default, fail if warnings are raised * Use GenericAPIView for GetAuthToken * Use GenericAPIView for RolesDetail endpoint * Refactor more endpoints to use GenericApiView * More API cleanup * Add extra type hints for exposed methods * Update RoleDetails endpoint - Specify serializer - Use RetrieveAPI class type * More type hints * Export API docs as part of CI * add more api views docs * even more docs * extend tests to api-version * simplify serializer * and more docs * fix serializer * added more API docs * clean diff * Added APISearch base * do not assume you know the user he might be anonymously creating the schema ;-) * set empty serializer where no input is needed * Use dummy model for schema generation * fix OpenAPI docs section * only run if needed * remove schema task * Add version check * pin version * fix QC order * fix assign * refactor order * optimize compile times * fix assign * onyl use install * more fixing * use full update cycle * revert python change * use api_version * run py * why? * clean up output * only check for api version diff if api_version was not touched * add schema check again * use seperate filter for API * increment api_version * Added push step * seperate publishing step to lower complexity * fix naming * fix file ending * Update qc_checks.yaml --------- Co-authored-by: Oliver Walters --- .github/workflows/qc_checks.yaml | 63 +++++++++++++++++++++++++++++- InvenTree/InvenTree/api_version.py | 5 ++- ci/version_check.py | 7 ++++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/.github/workflows/qc_checks.yaml b/.github/workflows/qc_checks.yaml index fdeefc31f6..10b62a0c32 100644 --- a/.github/workflows/qc_checks.yaml +++ b/.github/workflows/qc_checks.yaml @@ -30,6 +30,7 @@ jobs: server: ${{ steps.filter.outputs.server }} migrations: ${{ steps.filter.outputs.migrations }} frontend: ${{ steps.filter.outputs.frontend }} + api: ${{ steps.filter.outputs.api }} steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # pin@v4.1.1 @@ -44,6 +45,8 @@ jobs: migrations: - '**/migrations/**' - '.github/workflows**' + api: + - 'InvenTree/InvenTree/api_version.py' frontend: - 'src/frontend/**' @@ -126,6 +129,8 @@ jobs: INVENTREE_PYTHON_TEST_SERVER: http://localhost:12345 INVENTREE_PYTHON_TEST_USERNAME: testuser INVENTREE_PYTHON_TEST_PASSWORD: testpassword + outputs: + version: ${{ steps.version.outputs.version }} steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # pin@v4.1.1 @@ -136,8 +141,64 @@ jobs: dev-install: true update: true - name: Export API Documentation + run: invoke schema --ignore-warnings + - name: Upload schema + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # pin@v3.1.3 + with: + name: schema.yml + path: InvenTree/schema.yml + - name: Download public schema + if: needs.paths-filter.outputs.api == 'false' run: | - invoke schema --ignore-warnings + pip install requests >/dev/null 2>&1 + version="$(python3 ci/version_check.py only_version 2>&1)" + echo "Version: $version" + url="https://raw.githubusercontent.com/inventree/schema/main/export/${version}/api.yaml" + echo "URL: $url" + curl -s -o api.yaml $url + echo "Downloaded api.yaml" + - name: Check for differences in schemas + if: needs.paths-filter.outputs.api == 'false' + run: | + diff --color -u schema.yml api.yaml + diff -u schema.yml api.yaml && echo "no difference in API schema " || echo "differences in API schema" && exit 2 + - name: Check schema - including warnings + run: invoke schema + continue-on-error: true + - name: Extract version for publishing + id: version + if: github.ref == 'refs/heads/master' && needs.paths-filter.outputs.api == 'true' + run: | + pip install requests >/dev/null 2>&1 + version="$(python3 ci/version_check.py only_version 2>&1)" + echo "Version: $version" + echo "version=$version" >> "$GITHUB_OUTPUT" + + schema-push: + name: Push new schema + runs-on: ubuntu-20.04 + needs: [paths-filter, schema] + if: needs.schema.result == 'success' && github.ref == 'refs/heads/master' && needs.paths-filter.outputs.api == 'true' + env: + version: ${{ needs.schema.outputs.version }} + + steps: + - uses: actions/checkout@v4 + with: + repository: inventree/schema + token: ${{ secrets.SCHEMA_PAT }} + - name: Download schema artifact + uses: actions/download-artifact@v3 + with: + name: schema.yml + - name: Move schema to correct location + run: | + echo "Version: $version" + mkdir export/${version} + mv schema.yml export/${version}/api.yaml + - uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: "Update API schema for ${version}" python: name: Tests - inventree-python diff --git a/InvenTree/InvenTree/api_version.py b/InvenTree/InvenTree/api_version.py index 38d08a7bf7..b742f29348 100644 --- a/InvenTree/InvenTree/api_version.py +++ b/InvenTree/InvenTree/api_version.py @@ -1,11 +1,14 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 166 +INVENTREE_API_VERSION = 167 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +v167 -> 2024-02-07: https://github.com/inventree/InvenTree/pull/6440 + - Fixes for OpenAPI schema generation + v166 -> 2024-02-04 : https://github.com/inventree/InvenTree/pull/6400 - Adds package_name to plugin API - Adds mechanism for uninstalling plugins via the API diff --git a/ci/version_check.py b/ci/version_check.py index 8bad299488..a46236508a 100644 --- a/ci/version_check.py +++ b/ci/version_check.py @@ -90,6 +90,13 @@ def check_version_number(version_string, allow_duplicate=False): if __name__ == '__main__': + if 'only_version' in sys.argv: + here = Path(__file__).parent.absolute() + version_file = here.joinpath('..', 'InvenTree', 'InvenTree', 'api_version.py') + text = version_file.read_text() + results = re.findall(r"""INVENTREE_API_VERSION = (.*)""", text) + print(results[0]) + exit(0) # GITHUB_REF_TYPE may be either 'branch' or 'tag' GITHUB_REF_TYPE = os.environ['GITHUB_REF_TYPE']