diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f80a342..0e86e41 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -53,6 +53,62 @@ jobs: path: build/build-*.zip if-no-files-found: error + website-build: + + needs: build + + runs-on: ubuntu-latest + + steps: + + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + lfs: true + + - name: Checkout required submodules + run: | + git submodule update --init --depth 1 scripts/build-tools + git submodule update --init --depth 1 scripts/changes + git submodule update --init --depth 1 docs/_theme + + - name: Install the tool dependencies + uses: jdx/mise-action@v4 + + - name: Install dependencies + run: scripts/install-dependencies.sh + + - name: Build website + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + scripts/build-website.sh + chmod -v -R +rX "_site/" + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v5 + + website-deploy: + + needs: website-build + if: ${{ github.ref == 'refs/heads/main' }} + + permissions: + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + runs-on: ubuntu-latest + + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v5 + sparkle-update: needs: build if: ${{ needs.build.outputs.released == 'true' }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8b0f495 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +**.xcuserdatad +.DS_Store +.env +.nova +/.local +/_site +/docs/.jekyll-cache +/docs/_site +/docs/releases +build +temp +xcuserdata/ diff --git a/.gitmodules b/.gitmodules index 3e8cf73..9a43f29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,10 +6,13 @@ url = git@github.com:inseven/interact.git [submodule "scripts/changes"] path = scripts/changes - url = git@github.com:jbmorley/changes.git + url = https://github.com/jbmorley/changes.git [submodule "scripts/build-tools"] path = scripts/build-tools - url = git@github.com:jbmorley/build-tools.git + url = https://github.com/jbmorley/build-tools.git [submodule "scripts/Sparkle"] path = scripts/Sparkle url = https://github.com/sparkle-project/Sparkle +[submodule "docs/_theme"] + path = docs/_theme + url = https://github.com/jbmorley/showcase-theme.git diff --git a/.tool-versions b/.tool-versions index f732415..173612d 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1,2 @@ python 3.12 +ruby 3.1.2 diff --git a/docs/404.md b/docs/404.md new file mode 100644 index 0000000..52f8de6 --- /dev/null +++ b/docs/404.md @@ -0,0 +1,6 @@ +--- +title: Not Found +layout: page +--- + +
The page you requested could not be found.
diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 0000000..65da8ac --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,23 @@ +source "https://rubygems.org" + +gem "jekyll", "~> 4.2.0" +gem "webrick", "~> 1.7" + +gem "theme", path: "_theme" + +group :jekyll_plugins do + gem 'jekyll-environment-variables' + gem "jekyll-feed", "~> 0.12" + gem "jekyll-image-size", "~> 1.2" + gem "jekyll-toc" +end + +# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem +# and associated library. +platforms :mingw, :x64_mingw, :mswin, :jruby do + gem "tzinfo", "~> 1.2" + gem "tzinfo-data" +end + +# Performance-booster for watching directories on Windows +gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin] diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock new file mode 100644 index 0000000..8b38020 --- /dev/null +++ b/docs/Gemfile.lock @@ -0,0 +1,103 @@ +PATH + remote: _theme + specs: + theme (0.5.0) + jekyll (~> 4.2) + +GEM + remote: https://rubygems.org/ + specs: + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + colorator (1.1.0) + concurrent-ruby (1.3.7) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + eventmachine (1.2.7) + fastimage (2.4.1) + ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86_64-darwin) + forwardable-extended (2.6.0) + http_parser.rb (0.8.1) + i18n (1.15.2) + concurrent-ruby (~> 1.0) + jekyll (4.2.2) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 1.0) + jekyll-sass-converter (~> 2.0) + jekyll-watch (~> 2.0) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.0) + liquid (~> 4.0) + mercenary (~> 0.4.0) + pathutil (~> 0.9) + rouge (~> 3.0) + safe_yaml (~> 1.0) + terminal-table (~> 2.0) + jekyll-environment-variables (1.0.1) + jekyll (>= 3.0, < 5.x) + jekyll-feed (0.17.0) + jekyll (>= 3.7, < 5.0) + jekyll-image-size (1.2.1) + fastimage (>= 1.8) + jekyll (>= 3.7) + jekyll-sass-converter (2.2.0) + sassc (> 2.0.1, < 3.0) + jekyll-toc (0.19.0) + jekyll (>= 3.9) + nokogiri (~> 1.12) + jekyll-watch (2.2.1) + listen (~> 3.0) + kramdown (2.5.2) + rexml (>= 3.4.4) + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.10.0) + logger + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + logger (1.7.0) + mercenary (0.4.0) + nokogiri (1.18.10-arm64-darwin) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-darwin) + racc (~> 1.4) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (6.0.2) + racc (1.8.1) + rb-fsevent (0.11.2) + rb-inotify (0.11.1) + ffi (~> 1.0) + rexml (3.4.4) + rouge (3.30.0) + safe_yaml (1.0.5) + sassc (2.4.0) + ffi (~> 1.9) + terminal-table (2.0.0) + unicode-display_width (~> 1.1, >= 1.1.1) + unicode-display_width (1.8.0) + webrick (1.9.2) + +PLATFORMS + arm64-darwin + x86_64-darwin + +DEPENDENCIES + jekyll (~> 4.2.0) + jekyll-environment-variables + jekyll-feed (~> 0.12) + jekyll-image-size (~> 1.2) + jekyll-toc + theme! + tzinfo (~> 1.2) + tzinfo-data + wdm (~> 0.1.1) + webrick (~> 1.7) + +BUNDLED WITH + 2.6.9 diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..9ff2364 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,41 @@ +theme: theme +title: TinyBoard +author: Jason Morley +email: support@jbmorley.co.uk +description: USB Keyboard Proxy +image: images/screenshot-default-social@2x.png +baseurl: "" +url: "https://tinyboard.jbmorley.co.uk" +repository: https://github.com/inseven/tinyboard +copyright: 2022-2026 Jason Morley + +navigation: + - title: TinyBoard + href: / + - title: Releases + href: /releases + - title: GitHub + href: https://github.com/inseven/tinyboard + - title: Donate + href: https://jbmorley.co.uk/donate/ + +footer: + - title: Privacy Policy + href: /privacy-policy + - title: Support + href: /support + - title: License + href: /license + - title: More Software + href: https://jbmorley.co.uk/software/ + +plugins: + - jekyll-feed + - jekyll-environment-variables + - jekyll-toc + - jekyll-image-size +destination: ../_site + +defaults: + - values: + layout: "page" diff --git a/docs/_theme b/docs/_theme new file mode 160000 index 0000000..0dc33bf --- /dev/null +++ b/docs/_theme @@ -0,0 +1 @@ +Subproject commit 0dc33bf0659184a866042568a1fefed8e7e5758b diff --git a/docs/assets/css/custom.css b/docs/assets/css/custom.css new file mode 100644 index 0000000..dc81beb --- /dev/null +++ b/docs/assets/css/custom.css @@ -0,0 +1,13 @@ +:root { + --brand-color: color(display-p3 0.542 0.364 0.796); + --showcase-color-high: color(display-p3 0.542 0.364 0.796); + --showcase-color-low: color(display-p3 0.303 0.124 0.557); +} + +@media (prefers-color-scheme: dark) { + :root { + --brand-color: color(display-p3 0.542 0.364 0.796); + --showcase-color-high: color(display-p3 0.542 0.364 0.796); + --showcase-color-low: color(display-p3 0.303 0.124 0.557); + } +} diff --git a/docs/images/icon_128x128.png b/docs/images/icon_128x128.png new file mode 100644 index 0000000..7135a42 Binary files /dev/null and b/docs/images/icon_128x128.png differ diff --git a/docs/images/icon_128x128@2x.png b/docs/images/icon_128x128@2x.png new file mode 100644 index 0000000..af0c6dd Binary files /dev/null and b/docs/images/icon_128x128@2x.png differ diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..60ab973 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,5 @@ +--- +layout: default +--- + +{% include icon-header.html %} diff --git a/docs/license/index.md b/docs/license/index.md new file mode 100644 index 0000000..5770493 --- /dev/null +++ b/docs/license/index.md @@ -0,0 +1,11 @@ +--- +title: License +--- + +TinyBoard is licensed under the MIT License (see [LICENSE](https://github.com/inseven/tinyboard/blob/main/LICENSE)). It depends on the following separately licensed third-party libraries and components: + +- [Diligence](https://github.com/inseven/diligence), MIT License +- [Glitter](https://github.com/inseven/glitter), MIT License +- [Interact](https://github.com/inseven/interact), MIT License +- [Licensable](https://github.com/inseven/licensable), MIT License +- [Sparkle](https://github.com/sparkle-project/Sparkle), Sparkle License diff --git a/docs/privacy-policy/index.md b/docs/privacy-policy/index.md new file mode 100644 index 0000000..5cd49a8 --- /dev/null +++ b/docs/privacy-policy/index.md @@ -0,0 +1,7 @@ +--- +title: Privacy Policy +--- + +TinyBoard does not collect or store any personal data. + +Should this policy change in the future, we will make all reasonable efforts to inform you and provide mechanisms to opt-out. diff --git a/docs/support/index.md b/docs/support/index.md new file mode 100644 index 0000000..6e62086 --- /dev/null +++ b/docs/support/index.md @@ -0,0 +1,10 @@ +--- +title: Support +--- + +TinyBoard is developed in the open on [GitHub](https://github.com/inseven/tinyboard). I'd love your feedback so please feel free to join the discussion on [known issues](https://github.com/inseven/tinyboard/issues), raise a [new issue](https://github.com/inseven/tinyboard/issues/new), drop me an [email](mailto:support@jbmorley.co.uk?subject=TinyBoard%20Support), or reach out on [Mastodon](https://mastodon.me.uk/web/@jbmorley). + +- [Known Issues](https://github.com/inseven/tinyboard/issues) +- [New Issue](https://github.com/inseven/tinyboard/issues/new) +- [Email](mailto:support@jbmorley.co.uk?subject=TinyBoard%20Support) +- [Mastodon](https://mastodon.me.uk/web/@jbmorley) diff --git a/scripts/build-website.sh b/scripts/build-website.sh new file mode 100755 index 0000000..a29a51a --- /dev/null +++ b/scripts/build-website.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# Copyright (c) 2022-2026 Jason Morley +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +set -e +set -o pipefail +set -x +set -u + +SCRIPTS_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +ROOT_DIRECTORY="$SCRIPTS_DIRECTORY/.." +WEBSITE_DIRECTORY="$ROOT_DIRECTORY/docs" + +source "$SCRIPTS_DIRECTORY/environment.sh" + +# Process the command line arguments. +POSITIONAL=() +SERVE=false +while [[ $# -gt 0 ]] +do + key="$1" + case $key in + -s|--serve) + SERVE=true + shift + ;; + *) + POSITIONAL+=("$1") + shift + ;; + esac +done + +# Update the release notes. +"$SCRIPTS_DIRECTORY/update-release-notes.sh" + +# Install the Jekyll dependencies. +export GEM_HOME="$ROOT_DIRECTORY/.local/ruby" +mkdir -p "$GEM_HOME" +export PATH="$GEM_HOME/bin":$PATH +gem install bundler +cd "$WEBSITE_DIRECTORY" +bundle install + +# Get the latest release URL. +if ! DOWNLOAD_URL=$(build-tools latest-github-release inseven tinyboard "TinyBoard-*.zip"); then + echo >&2 failed + exit 1 +fi +# Belt-and-braces check that we managed to get the download URL. +if [[ -z "$DOWNLOAD_URL" ]]; then + echo "Failed to get release download URL." + exit 1 +fi +export DOWNLOAD_URL + +# Determine the version. +VERSION_NUMBER=`changes version` +export VERSION_NUMBER + +# Build the website. +cd "$WEBSITE_DIRECTORY" +if $SERVE ; then + bundle exec jekyll serve --watch +else + bundle exec jekyll build +fi diff --git a/scripts/changes b/scripts/changes index 04dcb21..49d7216 160000 --- a/scripts/changes +++ b/scripts/changes @@ -1 +1 @@ -Subproject commit 04dcb210268151d00a208dd27f162b6bd9d7dc89 +Subproject commit 49d721695e0abbd859ee368186bca297261142d7 diff --git a/scripts/release-notes.md b/scripts/release-notes.md new file mode 100644 index 0000000..db3c5d7 --- /dev/null +++ b/scripts/release-notes.md @@ -0,0 +1,11 @@ +--- +title: Releases +--- + +{% for release in releases -%} +## {% if release.is_released %}{{ release.version }}{% else %}{{ release.version }} (Unreleased){% endif %} +{% for section in release.sections -%} +{% for change in section.changes | reverse -%} +- {{ change.description | regex_replace("\\s+\\(#(\\d+)\\)$", "") }}{% if change.scope %}{{ change.scope }}{% endif %} +{% endfor %}{% endfor %} +{% endfor %} diff --git a/scripts/update-release-notes.sh b/scripts/update-release-notes.sh new file mode 100755 index 0000000..436ff8b --- /dev/null +++ b/scripts/update-release-notes.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# Copyright (c) 2022-2026 Jason Morley +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +set -e +set -o pipefail +set -x +set -u + +SCRIPTS_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +ROOT_DIRECTORY="$SCRIPTS_DIRECTORY/.." +RELEASE_NOTES_TEMPLATE_PATH="$SCRIPTS_DIRECTORY/release-notes.md" +RELEASE_NOTES_DIRECTORY="$ROOT_DIRECTORY/docs/releases" +RELEASE_NOTES_PATH="$RELEASE_NOTES_DIRECTORY/index.md" + +source "$SCRIPTS_DIRECTORY/environment.sh" + +cd "$ROOT_DIRECTORY" + +mkdir -p "$RELEASE_NOTES_DIRECTORY" +changes notes --all --released --template "$RELEASE_NOTES_TEMPLATE_PATH" > "$RELEASE_NOTES_PATH"