diff --git a/.changelog-bugfix.md b/.changelog-bugfix.md index 266bfe0ed..184b179e7 100644 --- a/.changelog-bugfix.md +++ b/.changelog-bugfix.md @@ -5,3 +5,4 @@ - The presentation of algorithmic parameters in the documentation has been improved. - Outdated GitHub Actions can now be printed via the build target `check_github_actions`. Alternatively, the build target `update_github_actions` may be used to update them automatically. - Continuous Integration is now used to automatically update outdated GitHub Actions on a regular schedule. +- Continuous Integration is now used to periodically update the Doxygen configuration file used for generating API documentations for C++ code. diff --git a/.github/workflows/update_doxyfile.yml b/.github/workflows/update_doxyfile.yml new file mode 100644 index 000000000..bb3bcc8a8 --- /dev/null +++ b/.github/workflows/update_doxyfile.yml @@ -0,0 +1,62 @@ +--- +name: Update Doxyfile +on: + pull_request: + types: + - opened + - reopened + - synchronize + paths: + - .github/workflows/update_doxyfile.yml + - build + - build.bat + - build_system/main.py + - build_system/core/** + - build_system/util/** + - build_system/targets/paths.py + - build_system/targets/documentation/* + - build_system/targets/documentation/cpp/* + schedule: + - cron: 0 5 2 * * + workflow_dispatch: +jobs: + update_doxyfile: + name: Update Doxyfile + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: bugfix + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version-file: .version-python + - name: Setup git + uses: fregante/setup-git-user@v2 + - name: Generate token + uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ secrets.TOKEN_APP_ID }} + private-key: ${{ secrets.TOKEN_APP_SECRET }} + - name: Update Doxyfile + run: | + ./build update_doxyfile + git add build_system/targets/documentation/cpp/Doxyfile + - name: Submit pull request + id: pull-request + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ steps.app-token.outputs.token }} + commit-message: Update Doxyfile. + branch: update-doxyfile + title: Update Doxyfile + labels: bot + assignees: mrapp-ke + body: Update the Doxygen configuration file. + - name: Enable auto-merge + if: ${{ steps.pull-request.outputs.pull-request-operation == 'created' }} + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + run: gh pr merge --merge --auto "${{ steps.pull-request.outputs.pull-request-number }}" diff --git a/.github/workflows/update_github_actions.yml b/.github/workflows/update_github_actions.yml index 538cb1c74..50b405008 100644 --- a/.github/workflows/update_github_actions.yml +++ b/.github/workflows/update_github_actions.yml @@ -7,7 +7,7 @@ on: - reopened - synchronize paths: - - .github/workflows/test_changelog.yml + - .github/workflows/update_github_actions.yml - build - build.bat - build_system/main.py diff --git a/build_system/targets/dependencies/github/actions.py b/build_system/targets/dependencies/github/actions.py index 61ca1c1ab..105f7b4c9 100644 --- a/build_system/targets/dependencies/github/actions.py +++ b/build_system/targets/dependencies/github/actions.py @@ -178,7 +178,7 @@ def update_actions(self, *updated_actions: Action): self.write_lines(*updated_lines) def write_lines(self, *lines: str): - super().write_lines(lines) + super().write_lines(*lines) try: del self.uses_clauses @@ -261,7 +261,7 @@ def __query_latest_action_version(self, action: Action) -> ActionVersion: try: latest_tag = GithubApi(self.build_unit) \ - .set_token(self.__get_github_token()) \ + .set_token(self.github_token) \ .open_repository(repository_name) \ .get_latest_release_tag() diff --git a/build_system/targets/dependencies/github/pyyaml.py b/build_system/targets/dependencies/github/pyyaml.py index 0acd4e194..e7eb99b42 100644 --- a/build_system/targets/dependencies/github/pyyaml.py +++ b/build_system/targets/dependencies/github/pyyaml.py @@ -33,10 +33,11 @@ def yaml_dict(self) -> Dict: # pylint: disable=import-outside-toplevel import yaml with read_file(self.file) as file: - return yaml.load(file.read(), Loader=yaml.CLoader) + yaml_dict = yaml.load(file.read(), Loader=yaml.CLoader) + return yaml_dict if yaml_dict else {} def write_lines(self, *lines: str): - super().write_lines(lines) + super().write_lines(*lines) try: del self.yaml_dict diff --git a/build_system/targets/documentation/cpp/__init__.py b/build_system/targets/documentation/cpp/__init__.py index 4ad6c586f..7003af192 100644 --- a/build_system/targets/documentation/cpp/__init__.py +++ b/build_system/targets/documentation/cpp/__init__.py @@ -9,7 +9,7 @@ from core.targets import TargetBuilder from targets.documentation.cpp.modules import CppApidocModule -from targets.documentation.cpp.targets import ApidocCpp, ApidocIndexCpp +from targets.documentation.cpp.targets import ApidocCpp, ApidocIndexCpp, UpdateDoxyfile from targets.paths import Project APIDOC_CPP = 'apidoc_cpp' @@ -22,6 +22,8 @@ .add_build_target(APIDOC_CPP_INDEX) \ .depends_on(APIDOC_CPP) \ .set_runnables(ApidocIndexCpp()) \ + .add_phony_target('update_doxyfile') \ + .set_runnables(UpdateDoxyfile()) \ .build() MODULES = [ diff --git a/build_system/targets/documentation/cpp/doxygen.py b/build_system/targets/documentation/cpp/doxygen.py index 4561a274b..769f5dfbe 100644 --- a/build_system/targets/documentation/cpp/doxygen.py +++ b/build_system/targets/documentation/cpp/doxygen.py @@ -8,12 +8,22 @@ from core.build_unit import BuildUnit from util.env import set_env -from util.io import create_directories +from util.io import create_directories, delete_files from util.run import Program from targets.documentation.cpp.modules import CppApidocModule +def get_doxyfile(build_unit: BuildUnit) -> str: + """ + Returns the path to the Doxyfile. + + :param build_unit: The build unit, the Doxyfile belong to + :return: The path to the Doxyfile + """ + return path.join(build_unit.root_directory, 'Doxyfile') + + class Doxygen(Program): """ Allows to run the external program "doxygen". @@ -33,7 +43,7 @@ def __init__(self, build_unit: BuildUnit, module: CppApidocModule): :param build_unit: The build unit from which the program should be run :param module: The module, the program should be applied to """ - super().__init__('doxygen', path.join(build_unit.root_directory, 'Doxyfile')) + super().__init__('doxygen', get_doxyfile(build_unit)) self.module = module self.print_arguments(True) self.install_program(False) @@ -42,3 +52,22 @@ def __init__(self, build_unit: BuildUnit, module: CppApidocModule): def _before(self): create_directories(self.module.output_directory) + + +class DoxygenUpdate(Program): + """ + Allows to run the external program "doxygen -u". + """ + + def __init__(self, build_unit: BuildUnit): + """ + :param build_unit: The build unit from which the program should be run + """ + super().__init__('doxygen', '-u', get_doxyfile(build_unit)) + self.print_arguments(True) + self.install_program(False) + self.set_build_unit(build_unit) + self.build_unit = build_unit + + def _after(self): + delete_files(get_doxyfile(self.build_unit) + '.bak') diff --git a/build_system/targets/documentation/cpp/targets.py b/build_system/targets/documentation/cpp/targets.py index 44ca0cc69..30d22cf28 100644 --- a/build_system/targets/documentation/cpp/targets.py +++ b/build_system/targets/documentation/cpp/targets.py @@ -7,11 +7,11 @@ from core.build_unit import BuildUnit from core.modules import Module -from core.targets import BuildTarget +from core.targets import BuildTarget, PhonyTarget from util.log import Log from targets.documentation.cpp.breathe_apidoc import BreatheApidoc -from targets.documentation.cpp.doxygen import Doxygen +from targets.documentation.cpp.doxygen import Doxygen, DoxygenUpdate from targets.documentation.cpp.modules import CppApidocModule from targets.documentation.targets import ApidocIndex @@ -49,3 +49,16 @@ class ApidocIndexCpp(ApidocIndex): def __init__(self): super().__init__(MODULE_FILTER) + + +class UpdateDoxyfile(PhonyTarget.Runnable): + """ + Updates the Doxyfile used for generating API documentations for C++ code. + """ + + def __init__(self): + super().__init__(MODULE_FILTER) + + def run_all(self, build_unit: BuildUnit, _: List[Module]): + Log.info('Updating Doxyfile in directory "%s"...', build_unit.root_directory) + DoxygenUpdate(build_unit).run() diff --git a/build_system/targets/versioning/changelog.py b/build_system/targets/versioning/changelog.py index 39026e6a4..af8bb896a 100644 --- a/build_system/targets/versioning/changelog.py +++ b/build_system/targets/versioning/changelog.py @@ -182,7 +182,7 @@ def validate(self): self.__validate_line(current_line=None, previous_line=previous_line) def write_lines(self, *lines: str): - super().write_lines(lines) + super().write_lines(*lines) try: del self.parsed_lines diff --git a/build_system/targets/versioning/versioning.py b/build_system/targets/versioning/versioning.py index 58c364d86..ff67a16e9 100644 --- a/build_system/targets/versioning/versioning.py +++ b/build_system/targets/versioning/versioning.py @@ -102,7 +102,7 @@ def update(self, version: Version): Log.info('Updated version to "%s"', str(version)) def write_lines(self, *lines: str): - super().write_lines(lines) + super().write_lines(*lines) try: del self.version @@ -140,7 +140,7 @@ def update(self, development_version: int): Log.info('Updated development version to "%s"', str(development_version)) def write_lines(self, *lines: str): - super().write_lines(lines) + super().write_lines(*lines) try: del self.development_version diff --git a/doc/developer_guide/continuous_integration.md b/doc/developer_guide/continuous_integration.md index 39842a368..52f8b2e71 100644 --- a/doc/developer_guide/continuous_integration.md +++ b/doc/developer_guide/continuous_integration.md @@ -46,3 +46,4 @@ The following CI jobs are used for building our software for different target pl The CI jobs listed below are run periodically to perform different maintenance tasks, such as the automatic update of dependencies. - `update_github_actions.yml` checks for outdated GitHub Actions used in workflow definition files. In cases where any updates are necessary, a pull request with the respective changes is opened. If the pull request passes all {ref}`necessary checks `, it is merged automatically. Otherwise, manual intervention is needed. +- `update_doxyfile.yml` updates the [Doxygen](https://sourceforge.net/projects/doxygen/) configuration file, required for generating API documentations for C++ code, to stay up-to-date as new versions of this software are released.