diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index df07ae01..498f1565 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -8,7 +8,7 @@ on: - ".github/workflows/deploy-docs.yml" - "docs/**" - "platform/**" - - "www/**" + - "scripts/restore_release_docs.sh" workflow_dispatch: concurrency: @@ -42,14 +42,10 @@ jobs: with: version: nightly-new-compiler - - name: Create Pages tree - run: | - mkdir -p temp_docs - if [ -d www ]; then - cp -R www/. temp_docs/ - else - sed 's/LATESTVERSION/main/g' docs/index.html > temp_docs/index.html - fi + - name: Restore released docs + env: + GH_TOKEN: ${{ github.token }} + run: ./scripts/restore_release_docs.sh temp_docs - name: Generate main branch docs env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0b960529..51a91cbf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -365,30 +365,7 @@ jobs: - name: Restore published versioned docs env: GH_TOKEN: ${{ github.token }} - run: | - set -euo pipefail - - mkdir -p www .release/docs-downloads - releases_json="$(gh api "repos/${GITHUB_REPOSITORY}/releases?per_page=100")" - latest_stable="$(printf '%s' "$releases_json" | jq -r '[.[] | select(.draft == false and .prerelease == false)][0].tag_name // empty')" - - printf '%s' "$releases_json" | jq -r '.[] | select(.draft == false) | .tag_name' | while IFS= read -r release_name; do - [ -n "$release_name" ] || continue - download_dir=".release/docs-downloads/$release_name" - mkdir -p "$download_dir" - - if gh release download "$release_name" --pattern docs.tar.gz --dir "$download_dir" --clobber; then - mkdir -p "www/$release_name" - tar -xzf "$download_dir/docs.tar.gz" -C "www/$release_name" --strip-components=1 - echo "Restored docs for $release_name" - else - echo "No docs.tar.gz asset for $release_name; skipping" - fi - done - - if [ -n "$latest_stable" ]; then - sed "s/LATESTVERSION/$latest_stable/g" docs/index.html > www/index.html - fi + run: ./scripts/restore_release_docs.sh www - name: Snapshot existing docs uses: roc-lang/release-package/actions/docs-snapshot@d2560ead9f724bfaabfbc8134b8895e120171064 @@ -423,16 +400,14 @@ jobs: release_version: ${{ needs.build.outputs.release_version }} paths: | examples - www branch_prefix: release-followup base_branch: ${{ github.event.repository.default_branch }} - commit_message: Update docs and examples for ${{ needs.build.outputs.release_version }} - pr_title: Update docs and examples for ${{ needs.build.outputs.release_version }} + commit_message: Update examples for ${{ needs.build.outputs.release_version }} + pr_title: Update examples for ${{ needs.build.outputs.release_version }} pr_body: | Release follow-up for ${{ needs.build.outputs.release_version }}. - Updates checked-in examples to the published platform bundle and - adds the generated versioned documentation. + Updates checked-in examples to the published platform bundle. github_token: ${{ github.token }} - name: Create Pages tree diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ae556802..3d5df55d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -132,7 +132,8 @@ simple-http-server --nocache --index ``` The release workflow attaches `docs.tar.gz`, updates checked-in examples to the -new bundle URL, generates versioned docs under `www/`, and opens a follow-up PR -for those source changes. It also deploys the validated docs immediately. After -the follow-up PR merges, the Pages workflow deploys the committed release docs -plus freshly generated `main` docs. +new bundle URL, and opens a follow-up PR for those source changes. It also +reconstructs the versioned documentation site from release assets and deploys +the validated docs immediately. The Pages workflow performs the same +reconstruction and adds freshly generated `main` docs without committing +generated documentation to the repository. diff --git a/README.md b/README.md index e6e97c3d..311f3231 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,20 @@ The [examples](examples/) directory contains executable, application-shaped CLI programs for common tasks like reading files, running commands, constructing URLs, making HTTP requests, working with SQLite, and reading stdin. -If you want to run an example without building `basic-cli` from source, use a released bundle URL in place of `"../platform/main.roc"`. To run examples from a local checkout, build the platform first; see [CONTRIBUTING.md](CONTRIBUTING.md). +The examples are pinned to the [`0.21.0-rc4` release](https://github.com/roc-lang/basic-cli/releases/tag/0.21.0-rc4): + +```roc +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } +``` + +To run examples from a local checkout instead, build the platform first and use `"../platform/main.roc"`; see [CONTRIBUTING.md](CONTRIBUTING.md). HTTP examples use Roc's builtin `Json` parser and encoder directly through `Http.get!` and `Http.send_json!`. ## Documentation -- [latest release](https://roc-lang.github.io/basic-cli/) +- [`0.21.0-rc4` release documentation](https://roc-lang.github.io/basic-cli/0.21.0-rc4/) - [latest main branch](https://roc-lang.github.io/basic-cli/main/) ## Help diff --git a/examples/bytes-stdin-stdout.roc b/examples/bytes-stdin-stdout.roc index e424eb8a..661859c4 100644 --- a/examples/bytes-stdin-stdout.roc +++ b/examples/bytes-stdin-stdout.roc @@ -1,5 +1,5 @@ ## Copy raw bytes from standard input to standard output and report the total. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdin diff --git a/examples/command-line-args.roc b/examples/command-line-args.roc index e821ef30..e14b6265 100644 --- a/examples/command-line-args.roc +++ b/examples/command-line-args.roc @@ -1,5 +1,5 @@ ## Read native command-line arguments without losing non-Unicode data. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/command.roc b/examples/command.roc index 3b343ab6..48cd39b2 100644 --- a/examples/command.roc +++ b/examples/command.roc @@ -1,5 +1,5 @@ ## Run child processes, capture their output, and configure their environment. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/dir.roc b/examples/dir.roc index 1a31915e..4ee46e84 100644 --- a/examples/dir.roc +++ b/examples/dir.roc @@ -1,5 +1,5 @@ ## Create, inspect, and clean up a small directory tree. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/env-var.roc b/examples/env-var.roc index 9b2f42f2..01f905fd 100644 --- a/examples/env-var.roc +++ b/examples/env-var.roc @@ -1,5 +1,5 @@ ## Read native and UTF-8 environment variables. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/error-handling.roc b/examples/error-handling.roc index 65fe836b..b2888190 100644 --- a/examples/error-handling.roc +++ b/examples/error-handling.roc @@ -1,5 +1,5 @@ ## Handle common filesystem errors with tag-pattern matching. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/file-accessed-modified-created-time.roc b/examples/file-accessed-modified-created-time.roc index 99500b56..65b06c3e 100644 --- a/examples/file-accessed-modified-created-time.roc +++ b/examples/file-accessed-modified-created-time.roc @@ -1,5 +1,5 @@ ## Read a file's accessed, modified, and creation timestamps. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/file-permissions.roc b/examples/file-permissions.roc index 70b4a276..5304ff6b 100644 --- a/examples/file-permissions.roc +++ b/examples/file-permissions.roc @@ -1,5 +1,5 @@ ## Inspect whether a file is executable, readable, and writable. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/file-read-buffered.roc b/examples/file-read-buffered.roc index e06b1448..a336959b 100644 --- a/examples/file-read-buffered.roc +++ b/examples/file-read-buffered.roc @@ -1,5 +1,5 @@ ## Read a file incrementally with a buffer instead of loading it all at once. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/file-read-write.roc b/examples/file-read-write.roc index 24c1df57..cea64f91 100644 --- a/examples/file-read-write.roc +++ b/examples/file-read-write.roc @@ -1,5 +1,5 @@ ## Write a UTF-8 file, read it back, and delete it. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/file-size.roc b/examples/file-size.roc index b8709fd2..954b83e4 100644 --- a/examples/file-size.roc +++ b/examples/file-size.roc @@ -1,5 +1,5 @@ ## Report the size in bytes of a path supplied on the command line. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/hello-world.roc b/examples/hello-world.roc index be350a7c..1e9b01d0 100644 --- a/examples/hello-world.roc +++ b/examples/hello-world.roc @@ -1,5 +1,5 @@ ## Print a minimal greeting to standard output. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/hello.roc b/examples/hello.roc index 88846766..513cca95 100644 --- a/examples/hello.roc +++ b/examples/hello.roc @@ -1,5 +1,5 @@ ## Greet a name supplied as a native command-line argument. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/http-client.roc b/examples/http-client.roc index 57d02c3a..07513c56 100644 --- a/examples/http-client.roc +++ b/examples/http-client.roc @@ -1,6 +1,6 @@ ## Send HTTP requests and handle UTF-8, JSON, and transport failures. app [main!] { - pf: platform "../platform/main.roc", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst", http: "https://github.com/roc-lang/http/releases/download/1.0.0/6ZUwqYhCS8PU9Mo6MF7oV82ET2o7KYb57CLKDq4cq4sS.tar.zst", } diff --git a/examples/http.roc b/examples/http.roc index 1e91e6a7..16c57bca 100644 --- a/examples/http.roc +++ b/examples/http.roc @@ -1,6 +1,6 @@ ## Fetch UTF-8, JSON, and HTML responses from a local HTTP server. app [main!] { - pf: platform "../platform/main.roc", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst", http: "https://github.com/roc-lang/http/releases/download/1.0.0/6ZUwqYhCS8PU9Mo6MF7oV82ET2o7KYb57CLKDq4cq4sS.tar.zst", } diff --git a/examples/locale.roc b/examples/locale.roc index d7c0b5bc..5a825560 100644 --- a/examples/locale.roc +++ b/examples/locale.roc @@ -1,5 +1,5 @@ ## Parse, encode, and inspect the system's preferred locales. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/path.roc b/examples/path.roc index ed6267b8..1525e216 100644 --- a/examples/path.roc +++ b/examples/path.roc @@ -1,5 +1,5 @@ ## Inspect a path's filename, extension, representation, and filesystem type. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr exposing [OsStr] import pf.Stdout diff --git a/examples/print.roc b/examples/print.roc index 68e592dd..14c6bec0 100644 --- a/examples/print.roc +++ b/examples/print.roc @@ -1,5 +1,5 @@ ## Write lines, text, and lists to standard output and standard error. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/random.roc b/examples/random.roc index a2199785..db02d73d 100644 --- a/examples/random.roc +++ b/examples/random.roc @@ -1,5 +1,5 @@ ## Generate random 32-bit and 64-bit seed values. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/sqlite-basic.roc b/examples/sqlite-basic.roc index 6450b755..bb729bc5 100644 --- a/examples/sqlite-basic.roc +++ b/examples/sqlite-basic.roc @@ -1,5 +1,5 @@ ## Query a SQLite database and decode rows into application records. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Env diff --git a/examples/sqlite-everything.roc b/examples/sqlite-everything.roc index 374861e9..2bd74e13 100644 --- a/examples/sqlite-everything.roc +++ b/examples/sqlite-everything.roc @@ -1,5 +1,5 @@ ## Exercise SQLite queries, decoders, nullable values, and prepared writes. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Env diff --git a/examples/stdin-basic.roc b/examples/stdin-basic.roc index 9739bcda..a282ce7f 100644 --- a/examples/stdin-basic.roc +++ b/examples/stdin-basic.roc @@ -1,5 +1,5 @@ ## Prompt for two lines of standard input and print a greeting. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdin diff --git a/examples/stdin-pipe.roc b/examples/stdin-pipe.roc index 91cd52ae..57ed1faa 100644 --- a/examples/stdin-pipe.roc +++ b/examples/stdin-pipe.roc @@ -1,5 +1,5 @@ ## Read piped bytes to end-of-input and validate them as UTF-8. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdin diff --git a/examples/tcp-client.roc b/examples/tcp-client.roc index 2b7009a8..24eb426c 100644 --- a/examples/tcp-client.roc +++ b/examples/tcp-client.roc @@ -1,5 +1,5 @@ ## Exchange lines with a local TCP echo server using buffered stream operations. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Tcp diff --git a/examples/temp-dir.roc b/examples/temp-dir.roc index 4857032b..32c44176 100644 --- a/examples/temp-dir.roc +++ b/examples/temp-dir.roc @@ -1,5 +1,5 @@ ## Print the operating system's default temporary directory. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/terminal-app-snake.roc b/examples/terminal-app-snake.roc index 1a8555cd..9e28d7a5 100644 --- a/examples/terminal-app-snake.roc +++ b/examples/terminal-app-snake.roc @@ -1,5 +1,5 @@ ## Build a small full-screen snake game using terminal raw mode. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdin diff --git a/examples/time.roc b/examples/time.roc index 2508ea03..adf6325a 100644 --- a/examples/time.roc +++ b/examples/time.roc @@ -1,5 +1,5 @@ ## Measure a sleep interval and format the current UTC time. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/tty.roc b/examples/tty.roc index 29d489e5..eef7c09b 100644 --- a/examples/tty.roc +++ b/examples/tty.roc @@ -1,5 +1,5 @@ ## Enable terminal raw mode, read one key, and restore normal behavior. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/examples/url.roc b/examples/url.roc index 60c88891..6226dc86 100644 --- a/examples/url.roc +++ b/examples/url.roc @@ -1,5 +1,5 @@ ## Build a validated search URL while encoding path and query components. -app [main!] { pf: platform "../platform/main.roc" } +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst" } import pf.OsStr import pf.Stdout diff --git a/scripts/restore_release_docs.sh b/scripts/restore_release_docs.sh new file mode 100755 index 00000000..4eb9bb25 --- /dev/null +++ b/scripts/restore_release_docs.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +set -euo pipefail + +docs_root="${1:?usage: restore_release_docs.sh DOCS_ROOT [DOWNLOAD_ROOT]}" +download_root="${2:-${RUNNER_TEMP:-.release}/basic-cli-docs}" +repository="${GITHUB_REPOSITORY:?GITHUB_REPOSITORY must be set}" + +mkdir -p "$docs_root" "$download_root" + +release_names="$( + gh api --paginate "repos/$repository/releases?per_page=100" \ + --jq '.[] | select(.draft == false) | .tag_name' +)" + +while IFS= read -r release_name; do + [ -n "$release_name" ] || continue + + release_download_root="$download_root/$release_name" + mkdir -p "$release_download_root" + + if gh release download "$release_name" \ + --repo "$repository" \ + --pattern docs.tar.gz \ + --dir "$release_download_root" \ + --clobber + then + mkdir -p "$docs_root/$release_name" + tar -xzf "$release_download_root/docs.tar.gz" \ + -C "$docs_root/$release_name" \ + --strip-components=1 + echo "Restored docs for $release_name" + else + echo "No docs.tar.gz asset for $release_name; skipping" + fi +done <<< "$release_names" + +latest_stable="$( + gh api "repos/$repository/releases/latest" --jq .tag_name 2>/dev/null || true +)" + +if [ -n "$latest_stable" ]; then + sed "s/LATESTVERSION/$latest_stable/g" docs/index.html > "$docs_root/index.html" +else + sed 's/LATESTVERSION/main/g' docs/index.html > "$docs_root/index.html" +fi