From 20ab7e8c8fb8976078678e931084016c30beed5e Mon Sep 17 00:00:00 2001 From: David Maas Date: Fri, 24 May 2024 12:27:42 -0500 Subject: [PATCH 1/3] Cleaned up and modernized build.yml * Made it so redundant builds are canceled. * Remove unnecessary MSBuild usage (docfx will restore automatically.) * Update to .NET 8 LTS. * Migrate to modern GitHub Pages deployment using official actions rather than community ones. --- .github/workflows/build.yml | 44 +++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 87b1e587..bb18d530 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,45 +1,41 @@ # Builds and publishes the documentation website to gh-pages branch -name: Build docs +name: Build documentation on: push: branches: [ main ] workflow_dispatch: +concurrency: + group: build + cancel-in-progress: true +permissions: + # Both required by actions/deploy-pages + pages: write + id-token: write jobs: build: + name: Build documentation runs-on: windows-latest steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4 name: Checkout with: submodules: recursive - - name: Setup MSBuild - uses: microsoft/setup-msbuild@v2 - - - name: Restore NuGet Packages - run: msbuild -t:restore src\bonsai\Bonsai.sln - - - name: Setup .NET Core SDK - uses: actions/setup-dotnet@v4.0.0 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: - dotnet-version: 7.x + dotnet-version: 8.x - name: Setup DocFX run: dotnet tool restore - - name: Build Documentation + - name: Build documentation run: dotnet docfx docfx.json - - - name: Checkout gh-pages - uses: actions/checkout@v4.1.1 - with: - ref: gh-pages - path: gh-pages - - name: Publish to github pages - uses: peaceiris/actions-gh-pages@v3.9.3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: _site - force_orphan: true \ No newline at end of file + + - name: Upload GitHub Pages Artifact + uses: actions/upload-pages-artifact@v3 + + - name: Deploy to GitHub Pages + uses: actions/deploy-pages@v4 From b5033e090826356cbd75f4e9cf332003bca4f60d Mon Sep 17 00:00:00 2001 From: David Maas Date: Fri, 24 May 2024 11:11:45 -0500 Subject: [PATCH 2/3] Automate bumping version numbers for release automation --- .github/workflows/gha.py | 103 ++++++++++++++++++ .../workflows/update-bonsai-version-info.py | 72 ++++++++++++ .github/workflows/version-bump.yml | 93 ++++++++++++++++ .github/workflows/version-info-template.md | 4 + articles/installation.md | 6 +- 5 files changed, 276 insertions(+), 2 deletions(-) create mode 100755 .github/workflows/gha.py create mode 100755 .github/workflows/update-bonsai-version-info.py create mode 100644 .github/workflows/version-bump.yml create mode 100644 .github/workflows/version-info-template.md diff --git a/.github/workflows/gha.py b/.github/workflows/gha.py new file mode 100755 index 00000000..d67ec548 --- /dev/null +++ b/.github/workflows/gha.py @@ -0,0 +1,103 @@ +# GitHub Actions Utility Functions +# https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions +import os +import sys + +errors_were_printed = False + +def fail_if_errors(): + if errors_were_printed: + print("Exiting due to previous errors.") + sys.exit(1) + +def print_error(message): + global errors_were_printed + errors_were_printed = True + print(f"::error::{message}") + +def print_warning(message): + print(f"::warning::{message}") + +def print_notice(message): + print(f"::notice::{message}") + +def print_debug(message): + print(f"::debug::{message}") + +def github_file_command(command, message): + command = f"GITHUB_{command}" + command_file = os.getenv(command) + + if command_file is None: + print_error(f"Missing required GitHub environment variable '{command}'") + sys.exit(1) + + if not os.path.exists(command_file): + print_error(f"'{command}' points to non-existent file '{command_file}')") + sys.exit(1) + + with open(command_file, 'a') as command_file_handle: + command_file_handle.write(message) + command_file_handle.write('\n') + +def set_output(name, value): + if isinstance(value, bool): + value = "true" if value else "false" + github_file_command("OUTPUT", f"{name}< 0: + print_error("Bad command line, too many arguments specified.") + sys.exit(1) + + pop_arg() # Skip script name + command = pop_arg() + if command == "print_error": + message = pop_arg() + done_parsing() + print_error(message) + elif command == "print_warning": + message = pop_arg() + done_parsing() + print_warning(message) + elif command == "print_notice": + message = pop_arg() + done_parsing() + print_notice(message) + elif command == "set_output": + name = pop_arg() + value = pop_arg() + done_parsing() + set_output(name, value) + elif command == "set_environment_variable": + name = pop_arg() + value = pop_arg() + done_parsing() + set_environment_variable(name, value) + elif command == "add_path": + path = pop_arg() + done_parsing() + add_path(path) + else: + print_error(f"Unknown command '{command}'") + sys.exit(1) + + fail_if_errors() diff --git a/.github/workflows/update-bonsai-version-info.py b/.github/workflows/update-bonsai-version-info.py new file mode 100755 index 00000000..f9edab38 --- /dev/null +++ b/.github/workflows/update-bonsai-version-info.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +import os +import re + +import gha + +TEMPLATE_PATH = ".github/workflows/version-info-template.md" +INSTALLATION_ARTICLE_PATH = "articles/installation.md" + +project_url_base = "https://github.com/bonsai-rx/bonsai/" + +#================================================================================================== +# Get inputs +#================================================================================================== +def get_environment_variable(name) -> str: + ret = os.getenv(name) + + if ret is None or ret == '': + gha.print_error(f"Missing required parameter '{name}'") + return '' + + return ret + +workflow_dispatch_version = get_environment_variable('workflow_dispatch_version') + +# Handle forks for testing purposes +if os.getenv('is_canonical_docs_repo') != 'true': + project_fork_url = get_environment_variable('project_fork_url') + project_url_base = project_fork_url.removesuffix('.git') + if project_url_base[-1] != '/': + project_url_base += '/' + +gha.fail_if_errors() + +#================================================================================================== +# Populate template +#================================================================================================== + +version_info = "" +with open(TEMPLATE_PATH, 'r', encoding='utf-8') as f: + version_info = f.read() + +version_info = version_info.replace("$VERSION$", workflow_dispatch_version) +version_info = version_info.replace("$PROJECT_URL_BASE$", project_url_base) + +#================================================================================================== +# Update article +#================================================================================================== + +article = "" +with open(INSTALLATION_ARTICLE_PATH, 'r', encoding='utf-8') as f: + article = f.read() + +def replace_function(match): + return f"{match.group(1)}{version_info}{match.group(3)}" + +(article, replacement_count) = re.subn( + r'(\r?\n)(.+)()', + replace_function, + article, + 1, + re.DOTALL +) + +if replacement_count != 1: + gha.print_error(f"Failed to find the RELEASE_INFO block within '{INSTALLATION_ARTICLE_PATH}'.") + gha.fail_if_errors() + +with open(INSTALLATION_ARTICLE_PATH, 'w',encoding='utf-8') as f: + f.write(article) + +print(f"Bonsai release info in '{INSTALLATION_ARTICLE_PATH}' updated to {workflow_dispatch_version}.") diff --git a/.github/workflows/version-bump.yml b/.github/workflows/version-bump.yml new file mode 100644 index 00000000..816e61d5 --- /dev/null +++ b/.github/workflows/version-bump.yml @@ -0,0 +1,93 @@ +# This workflow bumps the submodule version used for a particular project +# In the case of Bonsai being updated, this also updates the installation page with the latest version info +name: Update documented project version +run-name: Update `${{github.event.inputs.project}}` to `${{github.event.inputs.version}}` +on: + workflow_dispatch: + inputs: + project: + description: "The name of the project to be updated (IE: a folder name within the src directory)" + required: true + version: + description: "The target version to update to (IE: a Git tag in the project)" + required: true + project-fork-url: + description: "Git URL of the project for testing in forks" + default: "" +concurrency: + group: version-bump +permissions: + # Required to trigger GitHub Pages deployment + actions: write + # Required to push changes + contents: write +jobs: + update: + name: Update ${{github.event.inputs.project}} to ${{github.event.inputs.version}} + runs-on: ubuntu-latest + env: + PROJECT: ${{github.event.inputs.project}} + VERSION: ${{github.event.inputs.version}} + steps: + # ----------------------------------------------------------------------- Checkout + - name: Checkout + uses: actions/checkout@v4 + + # ----------------------------------------------------------------------- Override the submodule URL + # This is to support testing release automation in forks, it is disabled for the canonical docs repo + - name: Override ${{github.event.inputs.project}}'s submodule URL + if: vars.IS_CANONICAL_DOCS_REPO != 'true' && github.event.inputs.project-fork-url != '' + run: git config --local --add "submodule.src/$PROJECT.url" "$FORK_URL" + env: + FORK_URL: ${{github.event.inputs.project-fork-url}} + + # ----------------------------------------------------------------------- Update the submodule + - name: Clone ${{github.event.inputs.project}} submodule + run: git submodule update --init "src/$PROJECT/" + - name: Update ${{github.event.inputs.project}} submodule + working-directory: src/${{github.event.inputs.project}}/ + run: git checkout "refs/tags/$VERSION" + - name: Stage ${{github.event.inputs.project}} submodule + run: git add "src/$PROJECT/" + + # ----------------------------------------------------------------------- Update the installation page + - name: Setup Python 3.11 + if: github.event.inputs.project == 'bonsai' + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: Update Bonsai version info + if: github.event.inputs.project == 'bonsai' + run: | + python .github/workflows/update-bonsai-version-info.py + git add articles/installation.md + env: + workflow_dispatch_version: ${{github.event.inputs.version}} + is_canonical_docs_repo: ${{vars.IS_CANONICAL_DOCS_REPO}} + project_fork_url: ${{github.event.inputs.project-fork-url}} + + # ----------------------------------------------------------------------- Commit changes + # Skip the rest of the job if there aren't any changes to commit + # (IE: the submodule was already the relevant version) + - name: Check if update was necessary + id: pre-commit-check + run: | + (git diff-index --cached --exit-code HEAD \ + && python .github/workflows/gha.py print_notice "Version bump was no-op, no changes to commit.") \ + || python .github/workflows/gha.py set_output continue true + - name: Commit changes + if: steps.pre-commit-check.outputs.continue == 'true' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git commit -m "Update \`$PROJECT\` to \`$VERSION\`" + - name: Push changes + if: steps.pre-commit-check.outputs.continue == 'true' + run: git push + # The above push will not actually trigger a deployment as actions performed using temporary GitHub Actions tokens + # do not trigger events in order to avoid unintentional recursion. As such we manually trigger deployment. + - name: Trigger GitHub Pages deployment + if: steps.pre-commit-check.outputs.continue == 'true' + run: gh workflow run build.yml + env: + GH_TOKEN: ${{github.token}} diff --git a/.github/workflows/version-info-template.md b/.github/workflows/version-info-template.md new file mode 100644 index 00000000..c7cb3b30 --- /dev/null +++ b/.github/workflows/version-info-template.md @@ -0,0 +1,4 @@ +The latest stable release is: **$VERSION$** + +[ Download Installer (.exe)]($PROJECT_URL_BASE$releases/download/$VERSION$/Bonsai-$VERSION$.exe){class="btn btn-success"} +[ Download Portable (.zip)]($PROJECT_URL_BASE$releases/download/$VERSION$/Bonsai.zip){class="btn btn-warning"} diff --git a/articles/installation.md b/articles/installation.md index 9ea91ad3..0e35e2de 100644 --- a/articles/installation.md +++ b/articles/installation.md @@ -5,11 +5,13 @@ title: "Installing Bonsai" # Installing Bonsai -The Bonsai editor is currently designed to work with the .NET framework on Windows desktop operating systems, version 7 or later. The easiest way to get started with Bonsai is by downloading the latest installer. +The Bonsai editor is currently designed to work with the .NET Framework on Windows desktop operating systems, version 7 or later. The easiest way to get started with Bonsai is by downloading the latest installer. -The latest stable release is: **2.8.3 (2.8.3.4546)** + +The latest stable release is: **2.8.3** [ Download Installer (.exe)](https://github.com/bonsai-rx/bonsai/releases/download/2.8.3/Bonsai-2.8.3.exe){class="btn btn-success"} [ Download Portable (.zip)](https://github.com/bonsai-rx/bonsai/releases/download/2.8.3/Bonsai.zip){class="btn btn-warning"} + The installer will make sure that .NET and any other required system dependencies for running Bonsai are correctly setup in your computer. \ No newline at end of file From 0172a7d75cceeea22f7297b96d3dfc4df6a371ab Mon Sep 17 00:00:00 2001 From: David Maas Date: Wed, 3 Jul 2024 20:13:39 -0500 Subject: [PATCH 3/3] Add CI status badge to readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index cb537966..26d2a068 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Bonsai Documentation +[![](https://img.shields.io/github/actions/workflow/status/bonsai-rx/docs/build.yml?branch=main&style=flat-square&label=Deployment%20status)](https://github.com/bonsai-rx/docs/actions/workflows/build.yml) + This repo contains the technical reference manual for the Bonsai visual programming language, in addition to articles and examples that document the collective knowledge of the Bonsai user community. # Would you like to contribute to this repo?