Test failure 11m 20s
Annotations 2
error
Process completed with exit code 1.
warning
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/setup-go@v5. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
- Current runner version: 'v0.5.0'
- GITHUB_TOKEN Permissions
- Contents: read
- Metadata: read
- Packages: read
- Secret source: Actions
- Cache mode: write
- Prepare workflow directory
- Prepare all required actions
- Getting action download info
- Download action repository 'actions/checkout@v6' (SHA:d23441a48e516b6c34aea4fa41551a30e30af803)
- Download action repository 'actions/setup-go@v5' (SHA:40f1582b2485089dde7abd97c1529aa768e1baff)
- Complete job name: Test
- Checking docker version
- ##[command]/usr/bin/docker version --format '{{.Server.APIVersion}}'
- '1.56'
- Docker daemon API version: '1.56'
- ##[command]/usr/bin/docker version --format '{{.Client.APIVersion}}'
- '1.56'
- Docker client API version: '1.56'
- Clean up resources from previous jobs
- ##[command]/usr/bin/docker ps --all --quiet --no-trunc --filter "label=423db7"
- ##[command]/usr/bin/docker network prune --force --filter "label=423db7"
- Create local container network
- ##[command]/usr/bin/docker network create --label 423db7 github_network_40ce9edffbdd4c32a84ae386508ecceb
- 9e2a100c8b932d41021bebca4a3478d056c6b3c2ad057a69712b3bd55ad40a64
- Starting job container
- ##[command]/usr/bin/docker pull archlinux:latest
- latest: Pulling from library/archlinux
- 7450fb54bb4f: Pulling fs layer
- e4c7c6c5e741: Pulling fs layer
- e4c7c6c5e741: Download complete
- 7450fb54bb4f: Download complete
- 7450fb54bb4f: Pull complete
- e4c7c6c5e741: Pull complete
- Digest: sha256:e43f1fd80e073992c5f173efbbbf65144170bf60aeb7369940087d63eacea8f4
- Status: Downloaded newer image for archlinux:latest
- docker.io/library/archlinux:latest
- ##[command]/usr/bin/docker create --name 41d7e15d96cb476cacaaf7eba549d051_archlinuxlatest_dabbed --label 423db7 --workdir /__w/ermite/ermite --network github_network_40ce9edffbdd4c32a84ae386508ecceb -e "HOME=/github/home" -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work":"/__w" -v "/home/runner/externals":"/__e":ro -v "/home/runner/work/_temp":"/__w/_temp" -v "/home/runner/work/_actions":"/__w/_actions" -v "/opt/hostedtoolcache":"/__t" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" --entrypoint "tail" archlinux:latest "-f" "/dev/null"
- ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67
- ##[command]/usr/bin/docker start ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67
- ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67
- ##[command]/usr/bin/docker ps --all --filter id=ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67 --filter status=running --no-trunc --format "{{.ID}} {{.Status}}"
- ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67 Up Less than a second
- ##[command]/usr/bin/docker inspect --format "{{range .Config.Env}}{{println .}}{{end}}" ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67
- HOME=/github/home
- GITHUB_ACTIONS=true
- CI=true
- PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- LANG=C.UTF-8
- Waiting for all services to be ready
- Run pacman -Syu --noconfirm --needed git gcc openssh nodejs
- <U+001B>[36;1mpacman -Syu --noconfirm --needed git gcc openssh nodejs<U+001B>[0m
- shell: sh -e {0}
- env:
- GOWORK: off
- :: Synchronizing package databases...
- core downloading...
- extra downloading...
- :: Starting full system upgrade...
- resolving dependencies...
- looking for conflicting packages...
- Package (25) Old Version New Version Net Change Download Size
- extra/abseil-cpp 20260817.0-2 7.15 MiB 1.35 MiB
- extra/ada 4.0.0-1 0.95 MiB 0.31 MiB
- extra/c-ares 1.34.8-1 0.53 MiB 0.23 MiB
- core/ca-certificates-mozilla 3.131-1 3.131.1-1 -0.01 MiB 0.37 MiB
- core/db5.3 5.3.28-7 6.48 MiB 1.26 MiB
- core/dbus 1.16.2-1 1.16.2-2 0.03 MiB 0.35 MiB
- extra/gtest 1.18.0-1 1.67 MiB 0.39 MiB
- core/libedit 20260512_3.1-1 0.27 MiB 0.11 MiB
- core/libisl 0.28-1 5.90 MiB 0.94 MiB
- core/libmpc 1.4.1-1 0.19 MiB 0.09 MiB
- extra/libuv 1.52.1-2 0.64 MiB 0.26 MiB
- core/linux-api-headers 7.2-1 7.3-1 0.07 MiB 1.53 MiB
- core/perl 5.44.0-1 72.30 MiB 20.98 MiB
- extra/perl-error 0.17030-3 0.04 MiB 0.02 MiB
- extra/perl-mailtools 2.22-3 0.10 MiB 0.06 MiB
- extra/perl-timedate 2.35-1 0.15 MiB 0.06 MiB
- extra/simdjson 1:5.0.5-1 10.27 MiB 0.44 MiB
- core/systemd 262-1 262.1-1 0.03 MiB 10.68 MiB
- core/systemd-libs 262-1 262.1-1 0.01 MiB 1.44 MiB
- core/systemd-sysvcompat 262-1 262.1-1 0.00 MiB 0.01 MiB
- extra/zlib-ng 2.3.3-1 0.28 MiB 0.11 MiB
- core/gcc 16.2.1+r23+gd564253eb6c8-1 220.89 MiB 57.93 MiB
- extra/git 2.56.0-1 33.54 MiB 7.43 MiB
- extra/nodejs 26.12.0-1 64.12 MiB 17.48 MiB
- core/openssh 10.6p1-2 6.77 MiB 1.43 MiB
- Total Download Size: 125.26 MiB
- Total Installed Size: 485.67 MiB
- Net Upgrade Size: 432.35 MiB
- :: Proceed with installation? [Y/n]
- :: Retrieving packages...
- gcc-16.2.1+r23+gd564253eb6c8-1-x86_64 downloading...
- perl-5.44.0-1-x86_64 downloading...
- nodejs-26.12.0-1-x86_64 downloading...
- systemd-262.1-1-x86_64 downloading...
- git-2.56.0-1-x86_64 downloading...
- linux-api-headers-7.3-1-x86_64 downloading...
- systemd-libs-262.1-1-x86_64 downloading...
- openssh-10.6p1-2-x86_64 downloading...
- abseil-cpp-20260817.0-2-x86_64 downloading...
- db5.3-5.3.28-7-x86_64 downloading...
- libisl-0.28-1-x86_64 downloading...
- simdjson-1:5.0.5-1-x86_64 downloading...
- gtest-1.18.0-1-x86_64 downloading...
- ca-certificates-mozilla-3.131.1-1-x86_64 downloading...
- dbus-1.16.2-2-x86_64 downloading...
- ada-4.0.0-1-x86_64 downloading...
- libuv-1.52.1-2-x86_64 downloading...
- c-ares-1.34.8-1-x86_64 downloading...
- libedit-20260512_3.1-1-x86_64 downloading...
- zlib-ng-2.3.3-1-x86_64 downloading...
- libmpc-1.4.1-1-x86_64 downloading...
- perl-timedate-2.35-1-any downloading...
- perl-mailtools-2.22-3-any downloading...
- perl-error-0.17030-3-any downloading...
- systemd-sysvcompat-262.1-1-x86_64 downloading...
- checking keyring...
- checking package integrity...
- loading package files...
- checking for file conflicts...
- :: Processing package changes...
- upgrading linux-api-headers...
- installing db5.3...
- installing perl...
- installing perl-error...
- installing perl-timedate...
- installing perl-mailtools...
- installing zlib-ng...
- upgrading systemd-libs...
- upgrading ca-certificates-mozilla...
- installing git...
- Optional dependencies for git
- git-zsh-completion: upstream zsh completion
- tk: gitk and git gui
- openssh: ssh transport and crypto [pending]
- man: show help with `git command --help`
- perl-libwww: git svn
- perl-term-readkey: git svn and interactive.singlekey setting
- perl-io-socket-ssl: git send-email TLS support
- perl-authen-sasl: git send-email TLS support
- perl-cgi: gitweb (web interface) support
- python: git svn & git p4
- subversion: git svn
- org.freedesktop.secrets: keyring credential helper
- libsecret: libsecret credential helper [installed]
- less: the default pager for git
- installing libisl...
- installing libmpc...
- installing gcc...
- Optional dependencies for gcc
- lib32-gcc-libs: for generating code for 32-bit ABI
- installing libedit...
- installing openssh...
- Optional dependencies for openssh
- libfido2: FIDO/U2F support
- sh: for ssh-copy-id and findssl.sh [installed]
- x11-ssh-askpass: input passphrase in X
- xorg-xauth: X11 forwarding
- installing gtest...
- Optional dependencies for gtest
- python: gmock generator
- installing abseil-cpp...
- installing ada...
- installing c-ares...
- installing libuv...
- installing simdjson...
- installing nodejs...
- Optional dependencies for nodejs
- npm: nodejs package manager
- upgrading dbus...
- upgrading systemd...
- Creating group 'git' with GID 969.
- Creating user 'git' (git daemon user) with UID 969 and GID 969.
- upgrading systemd-sysvcompat...
- :: Running post-transaction hooks...
- ( 1/13) Creating system user accounts...
- ( 2/13) Creating temporary files...
- /usr/lib/tmpfiles.d/journal-nocow.conf:26: Failed to resolve specifier: uninitialized /etc/ detected, skipping.
- All rules containing unresolvable specifiers will be skipped.
- ( 3/13) Updating journal message catalog...
- ( 4/13) Updating udev hardware database...
- ( 5/13) Applying kernel sysctl settings...
- Skipped: Current root is not booted.
- ( 6/13) Reloading system manager configuration...
- Skipped: Current root is not booted.
- ( 7/13) Reloading user manager configuration...
- Skipped: Current root is not booted.
- ( 8/13) Enqueuing marked services...
- Skipped: Current root is not booted.
- ( 9/13) Reloading device manager configuration...
- Skipped: Current root is not booted.
- (10/13) Arming ConditionNeedsUpdate...
- (11/13) Rebuilding certificate stores...
- (12/13) Reloading system bus configuration...
- Skipped: Current root is not booted.
- (13/13) Checking for old perl modules...
- Run actions/checkout@v6
- with:
- repository: bnema/ermite
- token: ***
- ssh-strict: true
- ssh-user: git
- persist-credentials: true
- clean: true
- sparse-checkout-cone-mode: true
- fetch-depth: 1
- fetch-tags: false
- show-progress: true
- lfs: false
- submodules: false
- set-safe-directory: true
- allow-unsafe-pr-checkout: false
- env:
- GOWORK: off
- ##[command]/usr/bin/docker exec ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67 sh -c "cat /etc/*release | grep ^ID"
- Syncing repository: bnema/ermite
- Getting Git version info
- Working directory is '/__w/ermite/ermite'
- [command]/usr/sbin/git version
- git version 2.56.0
- Temporarily overriding HOME='/__w/_temp/e5dff91e-c635-4c1c-b4d8-17f89fa80cbd' before making global git config changes
- Adding repository directory to the temporary git global config as a safe directory
- [command]/usr/sbin/git config --global --add safe.directory /__w/ermite/ermite
- Deleting the contents of '/__w/ermite/ermite'
- Determining repository object format
- Initializing the repository
- [command]/usr/sbin/git init /__w/ermite/ermite
- hint: Using 'master' as the name for the initial branch. This default branch name
- hint: will change to "main" in Git 3.0. To configure the initial branch name
- hint: to use in all of your new repositories, which will suppress this warning,
- hint: call:
- hint:
- hint: git config --global init.defaultBranch <name>
- hint:
- hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
- hint: 'development'. The just-created branch can be renamed via this command:
- hint:
- hint: git branch -m <name>
- hint:
- hint: Disable this message with "git config set advice.defaultBranchName false"
- Initialized empty Git repository in /__w/ermite/ermite/.git/
- [command]/usr/sbin/git remote add origin http://ermite:7341/bnema/ermite
- Disabling automatic garbage collection
- [command]/usr/sbin/git config --local gc.auto 0
- Setting up auth
- Removing SSH command configuration
- [command]/usr/sbin/git config --local --name-only --get-regexp core\.sshCommand
- [command]/usr/sbin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
- Removing HTTP extra header
- [command]/usr/sbin/git config --local --name-only --get-regexp http\.http\:\/\/ermite\:7341\/\.extraheader
- [command]/usr/sbin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.http\:\/\/ermite\:7341\/\.extraheader' && git config --local --unset-all 'http.http://ermite:7341/.extraheader' || :"
- Removing includeIf entries pointing to credentials config files
- [command]/usr/sbin/git config --local --name-only --get-regexp ^includeIf\.gitdir:
- [command]/usr/sbin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url
- [command]/usr/sbin/git config --file /__w/_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config http.http://ermite:7341/.extraheader AUTHORIZATION: basic ***
- [command]/usr/sbin/git config --local includeIf.gitdir:/__w/ermite/ermite/.git.path /__w/_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git config --local includeIf.gitdir:/__w/ermite/ermite/.git/worktrees/*.path /__w/_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git config --local includeIf.gitdir:/github/workspace/.git.path /github/runner_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git config --local includeIf.gitdir:/github/workspace/.git/worktrees/*.path /github/runner_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- Fetching the repository
- [command]/usr/sbin/git -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin +4bec9a08f1d16de05320cc93a6cc759e32faa7a4:refs/remotes/origin/main
- From http://ermite:7341/bnema/ermite
- * [new ref] 4bec9a08f1d16de05320cc93a6cc759e32faa7a4 -> origin/main
- [command]/usr/sbin/git branch --list --remote origin/main
- origin/main
- [command]/usr/sbin/git rev-parse refs/remotes/origin/main
- 4bec9a08f1d16de05320cc93a6cc759e32faa7a4
- Determining the checkout info
- [command]/usr/sbin/git sparse-checkout disable
- [command]/usr/sbin/git config --local --unset-all extensions.worktreeConfig
- Checking out the ref
- [command]/usr/sbin/git checkout --progress --force -B main refs/remotes/origin/main
- Switched to a new branch 'main'
- branch 'main' set up to track 'origin/main'.
- [command]/usr/sbin/git log -1 --format=%H
- 4bec9a08f1d16de05320cc93a6cc759e32faa7a4
- Run git config --global --add safe.directory "$GITHUB_WORKSPACE"
- <U+001B>[36;1mgit config --global --add safe.directory "$GITHUB_WORKSPACE"<U+001B>[0m
- shell: sh -e {0}
- env:
- GOWORK: off
- Run actions/setup-go@v5
- with:
- go-version-file: go.mod
- cache: true
- check-latest: false
- env:
- GOWORK: off
- ##[command]/usr/bin/docker exec ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67 sh -c "cat /etc/*release | grep ^ID"
- Setup go version spec 1.27.1
- Attempting to download 1.27.1...
- (node:709) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
- (Use `node --trace-deprecation ...` to show where the warning was created)
- matching 1.27.1...
- Acquiring 1.27.1 from https://github.com/actions/go-versions/releases/download/1.27.1-33583469715/go-1.27.1-linux-x64.tar.gz
- Extracting Go...
- [command]/usr/sbin/tar xz --warning=no-unknown-keyword --overwrite -C /__w/_temp/acc4f977-dfc8-4688-9378-3613583d3a3d -f /__w/_temp/a7c8c01b-acd3-452a-9147-b319d85ca119
- Successfully extracted go to /__w/_temp/acc4f977-dfc8-4688-9378-3613583d3a3d
- Adding to the cache ...
- Successfully cached go to /__t/go/1.27.1/x64
- Added go to the path
- Successfully set up Go version 1.27.1
- [command]/__t/go/1.27.1/x64/bin/go env GOMODCACHE
- [command]/__t/go/1.27.1/x64/bin/go env GOCACHE
- /github/home/go/pkg/mod
- /github/home/.cache/go-build
- Cache is not found
- go version go1.27.1 linux/amd64
- go env
- AR='ar'
- CC='gcc'
- CGO_CFLAGS='-O2 -g'
- CGO_CPPFLAGS=''
- CGO_CXXFLAGS='-O2 -g'
- CGO_ENABLED='1'
- CGO_FFLAGS='-O2 -g'
- CGO_LDFLAGS='-O2 -g'
- CXX='g++'
- GCCGO='gccgo'
- GO111MODULE=''
- GOAMD64='v1'
- GOARCH='amd64'
- GOAUTH='netrc'
- GOBIN='/github/home/go/bin'
- GOCACHE='/github/home/.cache/go-build'
- GOCACHEPROG=''
- GODEBUG=''
- GOENV='/github/home/.config/go/env'
- GOEXE=''
- GOEXPERIMENT=''
- GOFIPS140='off'
- GOFLAGS=''
- GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1047086837=/tmp/go-build -gno-record-gcc-switches'
- GOHOSTARCH='amd64'
- GOHOSTOS='linux'
- GOINSECURE=''
- GOMOD='/__w/ermite/ermite/go.mod'
- GOMODCACHE='/github/home/go/pkg/mod'
- GONOPROXY=''
- GONOSUMDB=''
- GOOS='linux'
- GOPACKAGESDRIVER=''
- GOPATH='/github/home/go'
- GOPRIVATE=''
- GOPROXY='https://proxy.golang.org,direct'
- GOROOT='/__t/go/1.27.1/x64'
- GOSUMDB='sum.golang.org'
- GOTELEMETRY='local'
- GOTELEMETRYDIR='/github/home/.config/go/telemetry'
- GOTMPDIR=''
- GOTOOLCHAIN='auto'
- GOTOOLDIR='/__t/go/1.27.1/x64/pkg/tool/linux_amd64'
- GOVCS=''
- GOVERSION='go1.27.1'
- GOWORK='off'
- PKG_CONFIG='pkg-config'
- Run git --version
- <U+001B>[36;1mgit --version<U+001B>[0m
- <U+001B>[36;1mv=$(git --version | sed -E 's/^git version ([0-9]+)\.([0-9]+).*/\1 \2/')<U+001B>[0m
- <U+001B>[36;1mset -- $v<U+001B>[0m
- <U+001B>[36;1mif [ "$1" -lt 2 ] || { [ "$1" -eq 2 ] && [ "$2" -lt 45 ]; }; then<U+001B>[0m
- <U+001B>[36;1m echo "git 2.45 or newer is required" >&2<U+001B>[0m
- <U+001B>[36;1m exit 1<U+001B>[0m
- <U+001B>[36;1mfi<U+001B>[0m
- shell: sh -e {0}
- env:
- GOWORK: off
- git version 2.56.0
- Run go mod tidy
- <U+001B>[36;1mgo mod tidy<U+001B>[0m
- <U+001B>[36;1mgit diff --exit-code -- go.mod go.sum<U+001B>[0m
- shell: sh -e {0}
- env:
- GOWORK: off
- go: downloading github.com/bnema/hexcheck v0.4.0
- go: downloading github.com/bufbuild/buf v1.73.0
- go: downloading google.golang.org/protobuf v1.36.12
- go: downloading github.com/vektra/mockery/v3 v3.8.0
- go: downloading github.com/a-h/templ v0.3.1020
- go: downloading github.com/air-verse/air v1.67.4
- go: downloading github.com/stretchr/testify v1.12.1
- go: downloading bnema.dev/ermite-api v0.13.0
- go: downloading bnema.dev/ermite-git v0.1.0
- go: downloading connectrpc.com/connect v1.21.0
- go: downloading github.com/bnema/zerowrap v1.4.1
- go: downloading golang.org/x/sys v0.49.0
- go: downloading bnema.dev/ermite-kv v0.1.0
- go: downloading golang.org/x/crypto v0.57.0
- go: downloading google.golang.org/genproto/googleapis/rpc v0.0.0-20260904194346-d0f1323225a4
- go: downloading github.com/go-webauthn/webauthn v0.18.2
- go: downloading github.com/ProtonMail/go-crypto v1.4.1
- go: downloading github.com/descope/virtualwebauthn v1.0.5
- go: downloading github.com/alecthomas/chroma/v2 v2.27.0
- go: downloading github.com/bnema/kvconf v0.1.2
- go: downloading github.com/spf13/cobra v1.10.2
- go: downloading github.com/yuin/goldmark v1.8.6
- go: downloading golang.org/x/term v0.46.0
- go: downloading golang.org/x/text v0.42.0
- go: downloading github.com/golang-jwt/jwt/v5 v5.3.1
- go: downloading bnema.dev/ermite-actions v0.2.0
- go: downloading golang.org/x/tools v0.51.0
- go: downloading buf.build/go/app v0.2.1-0.20260824172350-b0e76892c61a
- go: downloading go.yaml.in/yaml/v3 v3.0.5
- go: downloading github.com/fatih/color v1.18.0
- go: downloading buf.build/go/bufplugin v0.10.0
- go: downloading buf.build/go/standard v0.1.1-0.20260325175353-2b287e071df5
- go: downloading github.com/rs/zerolog v1.35.1
- go: downloading gopkg.in/natefinch/lumberjack.v2 v2.2.1
- go: downloading github.com/stretchr/objx v0.5.3
- go: downloading github.com/go-viper/mapstructure/v2 v2.5.0
- go: downloading github.com/go-webauthn/x v0.3.1
- go: downloading github.com/google/go-tpm v0.9.8
- go: downloading github.com/google/uuid v1.6.0
- go: downloading github.com/tinylib/msgp v1.6.4
- go: downloading github.com/fxamacker/cbor/v2 v2.9.4
- go: downloading github.com/inconshreveable/mousetrap v1.1.0
- go: downloading github.com/spf13/pflag v1.0.10
- go: downloading github.com/dlclark/regexp2/v2 v2.2.1
- go: downloading github.com/google/go-cmp v0.7.0
- go: downloading go.uber.org/mock v0.6.0
- go: downloading github.com/alecthomas/assert/v2 v2.11.0
- go: downloading github.com/alecthomas/repr v0.5.2
- go: downloading gopkg.in/yaml.v3 v3.0.1
- go: downloading buf.build/go/interrupt v1.1.0
- go: downloading github.com/jedib0t/go-pretty/v6 v6.7.8
- go: downloading github.com/knadh/koanf/parsers/yaml v1.1.0
- go: downloading github.com/knadh/koanf/providers/structs v1.0.0
- go: downloading github.com/knadh/koanf/v2 v2.3.2
- go: downloading golang.org/x/sync v0.23.0
- go: downloading github.com/natefinch/atomic v1.0.1
- go: downloading github.com/cenkalti/backoff/v4 v4.3.0
- go: downloading github.com/cli/browser v1.3.0
- go: downloading github.com/fsnotify/fsnotify v1.9.0
- go: downloading dario.cat/mergo v1.0.2
- go: downloading github.com/andybalholm/brotli v1.2.0
- go: downloading github.com/gohugoio/hugo v0.164.0
- go: downloading github.com/joho/godotenv v1.5.1
- go: downloading github.com/pelletier/go-toml v1.9.5
- go: downloading github.com/google/go-containerregistry v0.22.1
- go: downloading buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.12-20260831211851-b4432e12a6e7.2
- go: downloading github.com/quic-go/quic-go v0.62.0
- go: downloading connectrpc.com/grpcreflect v1.3.0
- go: downloading github.com/bufbuild/protocompile v0.14.2-0.20260910151042-7436f7c76201
- go: downloading go.lsp.dev/jsonrpc2 v0.10.0
- go: downloading buf.build/go/bufprivateusage v0.1.0
- go: downloading connectrpc.com/otelconnect v0.9.0
- go: downloading github.com/bufbuild/protoplugin v0.0.0-20260414125817-25d1d281b46b
- go: downloading buf.build/go/protovalidate v1.4.0
- go: downloading buf.build/go/protoyaml v0.7.0
- go: downloading github.com/mattn/go-colorable v0.1.15
- go: downloading github.com/mattn/go-isatty v0.0.24
- go: downloading buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.12-20260722160903-4d94f3df3a7b.2
- go: downloading pluginrpc.com/pluginrpc v0.5.0
- go: downloading buf.build/gen/go/bufbuild/protodescriptor/protocolbuffers/go v1.36.12-20250109164928-1da0de137947.2
- go: downloading buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.2
- go: downloading github.com/klauspost/compress v1.20.0
- go: downloading github.com/x448/float16 v0.8.4
- go: downloading github.com/philhofer/fwd v1.2.0
- go: downloading github.com/cloudflare/circl v1.6.2
- go: downloading github.com/hexops/gotextdiff v1.0.3
- go: downloading github.com/cpuguy83/go-md2man/v2 v2.0.7
- go: downloading gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
- go: downloading github.com/fatih/structs v1.1.0
- go: downloading github.com/knadh/koanf/maps v0.1.2
- go: downloading github.com/mitchellh/copystructure v1.2.0
- go: downloading github.com/brunoga/deep v1.3.1
- go: downloading github.com/knadh/koanf/providers/env v1.1.0
- go: downloading github.com/knadh/koanf/providers/file v1.2.1
- go: downloading github.com/knadh/koanf/providers/posflag v1.0.1
- go: downloading github.com/xeipuuv/gojsonschema v1.2.0
- go: downloading golang.org/x/mod v0.41.0
- go: downloading github.com/jhump/protoreflect/v2 v2.0.0-beta.2
- go: downloading golang.org/x/net v0.59.0
- go: downloading github.com/a-h/parse v0.0.0-20250122154542-74294addb73e
- go: downloading github.com/mattn/go-runewidth v0.0.19
- go: downloading buf.build/go/spdx v0.2.0
- go: downloading github.com/moby/moby/api v1.56.0
- go: downloading github.com/moby/moby/client v0.6.0
- go: downloading github.com/jdx/go-netrc v1.0.0
- go: downloading github.com/xyproto/randomstring v1.0.5
- go: downloading github.com/opencontainers/go-digest v1.0.0
- go: downloading github.com/docker/cli v29.8.0+incompatible
- go: downloading github.com/rs/cors v1.11.1
- go: downloading buf.build/gen/go/bufbuild/registry/connectrpc/go v1.20.0-20260831211851-b4432e12a6e7.1
- go: downloading github.com/tetratelabs/wazero v1.12.0
- go: downloading cel.dev/cel-go v0.32.0
- go: downloading go.lsp.dev/protocol v0.12.0
- go: downloading go.lsp.dev/uri v0.3.0
- go: downloading go.uber.org/zap v1.28.0
- go: downloading mvdan.cc/xurls/v2 v2.6.0
- go: downloading github.com/quic-go/go-ossfuzz-seeds v0.1.0
- go: downloading github.com/quic-go/qpack v0.6.0
- go: downloading github.com/segmentio/encoding v0.5.4
- go: downloading github.com/gofrs/flock v0.13.1
- go: downloading go.opentelemetry.io/otel v1.46.0
- go: downloading go.opentelemetry.io/otel/metric v1.46.0
- go: downloading go.opentelemetry.io/otel/trace v1.46.0
- go: downloading go.opentelemetry.io/otel/sdk v1.46.0
- go: downloading go.opentelemetry.io/otel/sdk/metric v1.46.0
- go: downloading github.com/brianvoe/gofakeit/v6 v6.28.0
- go: downloading github.com/rodaine/protogofakeit v0.1.1
- go: downloading github.com/frankban/quicktest v1.14.6
- go: downloading buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.12-20241007202033-cf42259fcbfc.2
- go: downloading github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba
- go: downloading github.com/russross/blackfriday/v2 v2.1.0
- go: downloading github.com/kr/pretty v0.3.1
- go: downloading github.com/mitchellh/reflectwalk v1.0.2
- go: downloading github.com/huandu/xstrings v1.5.0
- go: downloading golang.org/x/exp v0.0.0-20260824195058-e88cd73687aa
- go: downloading github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415
- go: downloading github.com/klauspost/pgzip v1.2.6
- go: downloading github.com/clipperhouse/uax29/v2 v2.6.0
- go: downloading github.com/Microsoft/go-winio v0.6.2
- go: downloading github.com/containerd/errdefs v1.0.0
- go: downloading github.com/containerd/errdefs/pkg v0.3.0
- go: downloading github.com/distribution/reference v0.6.0
- go: downloading github.com/docker/go-connections v0.8.1
- go: downloading github.com/opencontainers/image-spec v1.1.1
- go: downloading go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.71.0
- go: downloading gotest.tools/v3 v3.5.2
- go: downloading github.com/moby/docker-image-spec v1.3.1
- go: downloading github.com/sirupsen/logrus v1.10.2
- go: downloading github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
- go: downloading cel.dev/expr v0.25.3
- go: downloading google.golang.org/genproto/googleapis/api v0.0.0-20260904194346-d0f1323225a4
- go: downloading go.lsp.dev/pkg v0.0.0-20210717090340-384b27a52fb2
- go: downloading go.uber.org/multierr v1.11.0
- go: downloading go.uber.org/goleak v1.3.0
- go: downloading github.com/segmentio/asm v1.2.1
- go: downloading github.com/go-logr/logr v1.4.4
- go: downloading github.com/go-logr/stdr v1.2.2
- go: downloading github.com/bep/godartsass/v2 v2.5.0
- go: downloading github.com/bep/golibsass v1.2.0
- go: downloading github.com/pelletier/go-toml/v2 v2.4.3
- go: downloading github.com/spf13/afero v1.15.0
- go: downloading github.com/tdewolff/parse/v2 v2.8.12
- go: downloading github.com/petermattis/goid v0.0.0-20260820044319-269ab09b5261
- go: downloading github.com/tidwall/btree v1.8.1
- go: downloading github.com/bmatcuk/doublestar/v4 v4.10.0
- go: downloading github.com/protocolbuffers/protoscope v0.0.0-20221109213918-8e7a6aafa2c9
- go: downloading github.com/rivo/uniseg v0.4.7
- go: downloading github.com/kr/text v0.2.0
- go: downloading github.com/rogpeppe/go-internal v1.15.0
- go: downloading github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb
- go: downloading github.com/docker/go-units v0.5.0
- go: downloading pgregory.net/rapid v1.2.0
- go: downloading github.com/felixge/httpsnoop v1.1.0
- go: downloading github.com/docker/docker-credential-helpers v0.9.9
- go: downloading github.com/antlr4-go/antlr/v4 v4.13.1
- go: downloading go.opentelemetry.io/auto/sdk v1.2.1
- go: downloading github.com/cespare/xxhash/v2 v2.3.0
- go: downloading github.com/tdewolff/test v1.0.12
- go: downloading github.com/bits-and-blooms/bitset v1.24.5
- go: downloading github.com/gobwas/glob v0.2.3
- go: downloading github.com/spf13/cast v1.10.0
- go: downloading github.com/gohugoio/hashstructure v0.6.0
- go: downloading github.com/bep/debounce v1.2.1
- go: downloading github.com/bep/gitmap v1.9.0
- go: downloading github.com/bep/helpers v0.12.0
- go: downloading github.com/bep/logg v0.4.0
- go: downloading github.com/gobuffalo/flect v1.0.3
- go: downloading github.com/gohugoio/go-radix v1.2.0
- go: downloading github.com/hairyhenderson/go-codeowners v0.7.0
- go: downloading github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c
- go: downloading github.com/bep/lazycache v0.8.1
- go: downloading github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69
- go: downloading github.com/gohugoio/httpcache v0.8.0
- go: downloading github.com/bep/clocks v0.5.0
- go: downloading github.com/bep/golocales v0.2.0
- go: downloading github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
- go: downloading github.com/jdkato/prose v1.2.1
- go: downloading github.com/kyokomi/emoji/v2 v2.2.13
- go: downloading github.com/olekukonko/tablewriter v1.1.4
- go: downloading github.com/bep/overlayfs v0.11.0
- go: downloading github.com/evanw/esbuild v0.28.1
- go: downloading github.com/bep/textandbinarywriter v0.1.0
- go: downloading github.com/gohugoio/go-i18n/v2 v2.1.3-0.20251018145728-cfcc22d823c6
- go: downloading github.com/clbanning/mxj/v2 v2.7.0
- go: downloading github.com/goccy/go-yaml v1.19.2
- go: downloading github.com/niklasfasching/go-org v1.9.1
- go: downloading github.com/gohugoio/gift v0.2.0
- go: downloading github.com/marekm4/color-extractor v1.2.1
- go: downloading github.com/pkg/errors v0.9.1
- go: downloading github.com/hashicorp/golang-lru/v2 v2.0.7
- go: downloading github.com/tdewolff/minify/v2 v2.24.13
- go: downloading github.com/bep/imagemeta v0.17.2
- go: downloading github.com/makeworld-the-better-one/dither/v2 v2.4.0
- go: downloading github.com/muesli/smartcrop v0.3.0
- go: downloading golang.org/x/image v0.43.0
- go: downloading github.com/olekukonko/ll v0.1.6
- go: downloading github.com/olekukonko/errors v1.2.0
- go: downloading github.com/gohugoio/hugo-goldmark-extensions/extras v0.7.0
- go: downloading github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.5.0
- go: downloading github.com/microcosm-cc/bluemonday v1.0.27
- go: downloading github.com/yuin/goldmark-emoji v1.0.6
- go: downloading github.com/bep/tmc v0.6.0
- go: downloading github.com/bep/goat v0.5.0
- go: downloading rsc.io/qr v0.2.0
- go: downloading github.com/getkin/kin-openapi v0.140.0
- go: downloading github.com/JohannesKaufmann/html-to-markdown/v2 v2.5.2
- go: downloading github.com/bep/goportabletext v0.2.0
- go: downloading github.com/clipperhouse/displaywidth v0.10.0
- go: downloading github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6
- go: downloading github.com/aymerick/douceur v0.2.0
- go: downloading github.com/JohannesKaufmann/dom v0.3.1
- go: downloading github.com/gorilla/css v1.0.1
- go: downloading github.com/santhosh-tekuri/jsonschema/v6 v6.0.2
- go: downloading github.com/oasdiff/yaml v0.1.0
- go: downloading github.com/go-openapi/jsonpointer v0.22.5
- go: downloading github.com/oasdiff/yaml3 v0.0.13
- go: downloading github.com/go-openapi/swag/jsonname v0.25.5
- Run scripts/templ-drift.sh
- <U+001B>[36;1mscripts/templ-drift.sh<U+001B>[0m
- shell: sh -e {0}
- env:
- GOWORK: off
- (✓) Post-generation event received, processing... [ updates=0 needsRestart=true needsBrowserReload=true ]
- (✓) Complete [ updates=0 duration=214.299041ms ]
- Run go vet ./...
- <U+001B>[36;1mgo vet ./...<U+001B>[0m
- shell: sh -e {0}
- env:
- GOWORK: off
- Run go test -race $(go list ./... | grep -vx 'bnema.dev/ermite/internal/app')
- <U+001B>[36;1mgo test -race $(go list ./... | grep -vx 'bnema.dev/ermite/internal/app')<U+001B>[0m
- shell: sh -e {0}
- env:
- GOWORK: off
- ? bnema.dev/ermite/cmd/ermite [no test files]
- ? bnema.dev/ermite/gen/ermite/storage [no test files]
- ok bnema.dev/ermite/internal/adapters/ciartifacts 1.041s
- ok bnema.dev/ermite/internal/adapters/cilogs 1.055s
- ok bnema.dev/ermite/internal/adapters/cisummaries 1.079s
- ok bnema.dev/ermite/internal/adapters/client 1.218s
- ok bnema.dev/ermite/internal/adapters/ermitegit 124.662s
- ok bnema.dev/ermite/internal/adapters/eventbus 1.033s
- ok bnema.dev/ermite/internal/adapters/gitcli 17.941s
- ok bnema.dev/ermite/internal/adapters/githttp 4.039s
- ok bnema.dev/ermite/internal/adapters/githubapi 1.326s
- ok bnema.dev/ermite/internal/adapters/githubraw 1.024s
- ok bnema.dev/ermite/internal/adapters/gitpush 1.589s
- ok bnema.dev/ermite/internal/adapters/gitremote 3.300s
- ok bnema.dev/ermite/internal/adapters/httpserver 1.317s
- ok bnema.dev/ermite/internal/adapters/kvstore 2.372s
- ? bnema.dev/ermite/internal/adapters/oidchttp [no test files]
- ok bnema.dev/ermite/internal/adapters/rpc 1.134s
- ok bnema.dev/ermite/internal/adapters/secretbox 1.032s
- ok bnema.dev/ermite/internal/adapters/sigverify 3.428s
- ok bnema.dev/ermite/internal/adapters/sshsig 1.043s
- ok bnema.dev/ermite/internal/adapters/web 51.374s
- ok bnema.dev/ermite/internal/adapters/webauthn 1.106s
- ok bnema.dev/ermite/internal/boundary 1.234s
- ok bnema.dev/ermite/internal/clientlimit 2.559s
- ok bnema.dev/ermite/internal/config 1.029s
- ok bnema.dev/ermite/internal/domain 3.806s
- ? bnema.dev/ermite/internal/ports [no test files]
- ? bnema.dev/ermite/internal/ports/mocks [no test files]
- ? bnema.dev/ermite/internal/readertest [no test files]
- ok bnema.dev/ermite/internal/usecase 27.993s
- ? bnema.dev/ermite/scripts/loadtest [no test files]
- Run go test -race ./internal/app/
- <U+001B>[36;1mgo test -race ./internal/app/<U+001B>[0m
- shell: sh -e {0}
- env:
- GOWORK: off
- --- FAIL: TestJobTokenWithContentsWritePushesButNotWorkflows (1.97s)
- ci_permissions_test.go:248:
- Error Trace: /__w/ermite/ermite/internal/app/ci_permissions_test.go:248
- Error: "[repo:\"proj\" id:9 number:7 attempt:1 workflow_path:\".github/workflows/p.yml\" workflow_name:\".github/workflows/p.yml\" title:\"add s.txt\" event:\"push\" ref:\"refs/heads/sentinel\" sha:\"38be28af312c7f61d9b2f9036b63b39dccc88f50\" actor:\"root\" status:CI_STATUS_QUEUED created_at:{seconds:1792557133 nanos:529292366} version:51 name:\".github/workflows/p.yml\" trusted:true repo:\"proj\" id:8 number:6 attempt:1 workflow_path:\".github/workflows/p.yml\" workflow_name:\".github/workflows/p.yml\" title:\"mv\" event:\"create\" ref:\"refs/heads/rworkflow\" sha:\"22cefb7a536b742ce6653274b002858eefa6f086\" actor:\"root\" status:CI_STATUS_QUEUED created_at:{seconds:1792557133 nanos:411314098} version:48 name:\".github/workflows/p.yml\" trusted:true repo:\"proj\" id:7 number:2 attempt:1 workflow_path:\".github/workflows/moved.yml\" workflow_name:\".github/workflows/moved.yml\" title:\"mv\" event:\"create\" ref:\"refs/heads/rworkflow\" sha:\"22cefb7a536b742ce6653274b002858eefa6f086\" actor:\"root\" status:CI_STATUS_QUEUED created_at:{seconds:1792557133 nanos:403571777} version:46 name:\".github/workflows/moved.yml\" trusted:true repo:\"proj\" id:6 number:5 attempt:1 workflow_path:\".github/workflows/p.yml\" workflow_name:\".github/workflows/p.yml\" title:\"mv\" event:\"push\" ref:\"refs/heads/rworkflow\" sha:\"22cefb7a536b742ce6653274b002858eefa6f086\" actor:\"root\" status:CI_STATUS_QUEUED created_at:{seconds:1792557133 nanos:395353203} version:44 name:\".github/workflows/p.yml\" trusted:true repo:\"proj\" id:5 number:1 attempt:1 workflow_path:\".github/workflows/moved.yml\" workflow_name:\".github/workflows/moved.yml\" title:\"mv\" event:\"push\" ref:\"refs/heads/rworkflow\" sha:\"22cefb7a536b742ce6653274b002858eefa6f086\" actor:\"root\" status:CI_STATUS_QUEUED created_at:{seconds:1792557133 nanos:386931084} version:42 name:\".github/workflows/moved.yml\" trusted:true repo:\"proj\" id:4 number:4 attempt:1 workflow_path:\".github/workflows/p.yml\" workflow_name:\".github/workflows/p.yml\" title:\"add feat.txt\" event:\"create\" ref:\"refs/heads/feat\" sha:\"e2934ac6ef1e16138a8d56d16c2016540fc622bd\" actor:\"root\" status:CI_STATUS_QUEUED created_at:{seconds:1792557132 nanos:141672357} version:20 name:\".github/workflows/p.yml\" trusted:true repo:\"proj\" id:3 number:3 attempt:1 workflow_path:\".github/workflows/p.yml\" workflow_name:\".github/workflows/p.yml\" title:\"add feat.txt\" event:\"push\" ref:\"refs/heads/feat\" sha:\"e2934ac6ef1e16138a8d56d16c2016540fc622bd\" actor:\"root\" status:CI_STATUS_QUEUED created_at:{seconds:1792557132 nanos:129882413} version:18 name:\".github/workflows/p.yml\" trusted:true repo:\"proj\" id:2 number:2 attempt:1 workflow_path:\".github/workflows/p.yml\" workflow_name:\".github/workflows/p.yml\" title:\"add .github/workflows/p.yml\" event:\"create\" ref:\"refs/heads/main\" sha:\"2c4838024ede7effbb94d85008b920829f76268b\" actor:\"root\" status:CI_STATUS_QUEUED created_at:{seconds:1792557132 nanos:43740428} version:13 name:\".github/workflows/p.yml\" trusted:true repo:\"proj\" id:1 number:1 attempt:1 workflow_path:\".github/workflows/p.yml\" workflow_name:\".github/workflows/p.yml\" title:\"add .github/workflows/p.yml\" event:\"push\" ref:\"refs/heads/main\" sha:\"2c4838024ede7effbb94d85008b920829f76268b\" actor:\"root\" status:CI_STATUS_QUEUED created_at:{seconds:1792557132 nanos:35605144} version:11 name:\".github/workflows/p.yml\" trusted:true]" should have 8 item(s), but has 9
- Test: TestJobTokenWithContentsWritePushesButNotWorkflows
- Messages: push and create of the owner's rworkflow and sentinel only
- --- FAIL: TestWebFilesGolden (1.66s)
- --- FAIL: TestWebFilesGolden/blob-markdown (0.07s)
- web_files_test.go:104:
- Error Trace: /__w/ermite/ermite/internal/app/web_test.go:104
- /__w/ermite/ermite/internal/app/web_files_test.go:104
- Error: Not equal:
- expected: "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<meta name=\"color-scheme\" content=\"light dark\">\n<title>docs/guide.md · files · example.test</title>\n<meta name=\"theme-color\" media=\"(prefers-color-scheme: light)\" content=\"#ffffff\">\n<meta name=\"theme-color\" media=\"(prefers-color-scheme: dark)\" content=\"#0c0c0c\">\n<meta name=\"apple-mobile-web-app-title\" content=\"ermite\">\n<link rel=\"icon\" type=\"image/svg+xml\" href=\"/-/static/img/icon.HASH.svg\">\n<link rel=\"apple-touch-icon\" href=\"/-/static/app/apple-touch-icon.HASH.png\">\n<link rel=\"manifest\" href=\"/-/static/app/manifest.HASH.webmanifest\">\n<link rel=\"preload\" href=\"/-/static/fonts/atkinson-next.HASH.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<link rel=\"stylesheet\" href=\"/-/static/css/ermite.HASH.css\">\n<meta name=\"htmx-config\" content='{\"history\":false,\"includeIndicatorCSS\":false,\"extensions\":\"sse, hx-live\"}'>\n<script src=\"/-/static/js/htmx.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/hx-live.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/hx-sse.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/store.HASH.js\">\n</script>\n<script src=\"/-/static/js/ermite.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/files.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/passkey.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/log.HASH.js\" defer>\n</script>\n</head>\n<body data-ref=\"main\" data-sha=\"SHA40\" data-sel=\"\" data-nav=\"\" data-paths=\"/files/paths/SHA40\" data-blob=\"/files/blob/main\">\n<a class=\"skip\" href=\"#main\">skip to content</a>\n<header class=\"hdr\">\n<div class=\"hdr-top\">\n<a class=\"brand\" href=\"/\" data-g=\"h\" aria-label=\"home\" title=\"home (g h)\">\n<span class=\"brand-mark\" aria-hidden=\"true\">\n</span>\n</a>\n<nav class=\"crumbs\" aria-label=\"Path\">\n<ol>\n<li>\n<a href=\"/files\">files</a>\n</li>\n<li>\n<a href=\"/files/tree/main\">blob</a>\n</li>\n<li>\n<a href=\"/files/tree/main\">main</a>\n</li>\n<li>\n<a href=\"/files/tree/main/docs\">docs</a>\n</li>\n<li>\n<a href=\"/files/blob/main/docs/guide.md\" aria-current=\"page\">guide.md</a>\n</li>\n</ol>\n</nav>\n<div class=\"hdr-acts\">\n<a class=\"btn ref\" href=\"/files/refs\" data-fire=\"refs\" aria-keyshortcuts=\"b\" title=\"switch branch or tag (b)\">\n<span class=\"ico i-branch\" aria-hidden=\"true\">\n</span>\n<span class=\"ref-name\">main</span>\n<span class=\"sha\">SHA7</span>\n</a>\n<button type=\"button\" class=\"btn search\" data-js aria-haspopup=\"dialog\" aria-controls=\"panel-cmd\" aria-keyshortcuts=\"Control+K :\" title=\"go to a section, ref, file or repo (ctrl k or :)\" data-fire=\"cmd\">\n<span class=\"ico i-search\" aria-hidden=\"true\">\n</span>\n<span class=\"search-label\">Go to…</span>\n<kbd aria-hidden=\"true\">ctrl k</kbd>\n</button>\n</div>\n</div>\n<nav class=\"tabs\" aria-label=\"Sections\">\n<ul>\n<li>\n<a href=\"/files\" data-key=\"s\" aria-keyshortcuts=\"s\">Summary <kbd aria-hidden=\"true\">s</kbd>\n</a>\n</li>\n<li>\n<a href=\"/files/tree/main\" data-key=\"t\" aria-keyshortcuts=\"t\" aria-current=\"page\">Files <kbd aria-hidden=\"true\">t</kbd>\n</a>\n</li>\n<li>\n<a href=\"/files/commits/main\" data-key=\"c\" aria-keyshortcuts=\"c\">Commits <kbd aria-hidden=\"true\">c</kbd>\n</a>\n</li>\n<li>\n<a href=\"/files/refs\" data-key=\"r\" aria-keyshortcuts=\"r\">Branches & tags <kbd aria-hidden=\"true\">r</kbd>\n</a>\n</li>\n<li>\n<a href=\"/files/merge-requests\" data-key=\"m\" aria-keyshortcuts=\"m\">Merge requests <kbd aria-hidden=\"true\">m</kbd>\n</a>\n</li>\n<li>\n<a href=\"/files/actions\" data-key=\"a\" aria-keyshortcuts=\"a\">Actions <kbd aria-hidden=\"true\">a</kbd>\n</a>\n</li>\n</ul>\n</nav>\n</header>\n<div class=\"work has-rail\">\n<main id=\"main\" tabindex=\"-1\">\n<h1 class=\"file-h\">\n<span>guide.md</span>\n<span class=\"acts\">\n<a class=\"btn\" href=\"/files/raw/main/docs/guide.md\">Raw</a>\n<a class=\"btn\" href=\"/files/commits/main/docs/guide.md\">History</a>\n<a class=\"btn\" href=\"/files/tree/main/docs\">Folder</a>\n</span>\n</h1>\n<article class=\"prose\" aria-label=\"guide.md\" hx-ignore>\n<h1 id=\"md-guide\">Guide</h1>\n<h2 id=\"md-steps\">Steps</h2>\n<p>Run it.</p>\n<pre>\n<code class=\"language-sh\">make all\n</code>\n</pre>\n</article>\n<details class=\"source\">\n<summary>source</summary>\n<pre class=\"chroma code\" data-anchor=\"\" hx-on:click=\"let a = event.target.closest('a.ln'); if (!a) return; event.preventDefault();\n let n = +a.textContent; if (!event.shiftKey || !data.anchor) data.anchor = n;\n let lo = Math.min(+data.anchor, n), hi = Math.max(+data.anchor, n);\n history.replaceState(null, '', '#L' + lo + (hi > lo ? '-L' + hi : '')); trigger('sel')\" hx-on:sel=\"let m = location.hash.match(/^#L(\\d+)(?:-L(\\d+))?$/); let lo = m ? +m[1] : 0, hi = m ? +(m[2] || m[1]) : 0;\n q('.line in this').arr().forEach(l => { let k = +l.id.slice(1); l.classList.toggle('sel', k >= lo && k <= hi) });\n document.body.dataset.sel = lo ? 'L' + lo + (hi > lo ? '-L' + hi + ' · ' + (hi - lo + 1) + ' lines' : '') : '';\n if (lo && event.detail?.scroll) document.getElementById('L' + lo)?.scrollIntoView({ block: 'center' })\" hx-live=\"if (!data.ready) { data.ready = '1'; trigger('sel', { scroll: true }) }\" data-ready=\"\">\n<code hx-ignore>\n<span class=\"line\" id=\"L1\">\n<a class=\"ln\" href=\"#L1\">1</a>\n<span class=\"gh\"># Guide</span>\n</span>\n<span class=\"line\" id=\"L2\">\n<a class=\"ln\" href=\"#L2\">2</a>\n</span>\n<span class=\"line\" id=\"L3\">\n<a class=\"ln\" href=\"#L3\">3</a>\n<span class=\"gu\">## Steps</span>\n</span>\n<span class=\"line\" id=\"L4\">\n<a class=\"ln\" href=\"#L4\">4</a>\n</span>\n<span class=\"line\" id=\"L5\">\n<a class=\"ln\" href=\"#L5\">5</a>Run it.</span>\n<span class=\"line\" id=\"L6\">\n<a class=\"ln\" href=\"#L6\">6</a>\n</span>\n<span class=\"line\" id=\"L7\">\n<a class=\"ln\" href=\"#L7\">7</a>\n<span class=\"s\">```sh</span>\n</span>\n<span class=\"line\" id=\"L8\">\n<a class=\"ln\" href=\"#L8\">8</a>make all</span>\n<span class=\"line\" id=\"L9\">\n<a class=\"ln\" href=\"#L9\">9</a>\n<span class=\"s\">```</span>\n</span>\n</code>\n</pre>\n</details>\n</main>\n<aside class=\"rail\" aria-label=\"Context\">\n<section aria-labelledby=\"r-file\">\n<h2 id=\"r-file\">File</h2>\n<dl class=\"kv\">\n<dt>size</dt>\n<dd>47 B</dd>\n<dt>lines</dt>\n<dd>9</dd>\n<dt>type</dt>\n<dd>markdown</dd>\n</dl>\n</section>\n<section aria-labelledby=\"r-last\">\n<h2 id=\"r-last\">Last change <a href=\"/files/commits/main/docs/guide.md\">History</a>\n</h2>\n<p>\n<a href=\"/files/commit/SHA40\">SHA7</a> add docs/guide.md</p>\n<p class=\"dim\">T · <time datetime=\"STAMP\" title=\"STAMP\">AGO</time>\n</p>\n</section>\n<section aria-labelledby=\"r-outline\">\n<h2 id=\"r-outline\">On this page</h2>\n<nav class=\"outline\" aria-label=\"Outline\">\n<a class=\"l1\" href=\"#md-guide\">Guide</a>\n<a class=\"l2\" href=\"#md-steps\">Steps</a>\n</nav>\n</section>\n<section aria-labelledby=\"r-sel\">\n<h2 id=\"r-sel\">Selection</h2>\n<p :text=\"document.body.dataset.sel || 'none · click a line number, shift-click extends'\">none · click a line number, shift-click extends</p>\n<p class=\"dim\">y copies a permalink pinned to the commit sha</p>\n</section>\n</aside>\n</div>\n<footer class=\"foot\">\n<span>ermite devel</span>\n<a href=\"http://example.test/ermite\" rel=\"noopener\" title=\"source of this version (AGPL-3.0-or-later)\">source</a>\n<button type=\"button\" class=\"foot-keys\" data-js data-fire=\"help\" aria-haspopup=\"dialog\" aria-controls=\"panel-help\" aria-keyshortcuts=\"?\">\n<kbd aria-hidden=\"true\">?</kbd> keyboard shortcuts</button>\n</footer>\n<div class=\"hint\" role=\"status\" aria-live=\"polite\">\n<span class=\"hint-nav\" :text=\"document.body.dataset.nav || ''\">\n</span>\n<span class=\"hint-sel\" :text=\"document.body.dataset.sel ? document.body.dataset.sel + ' · y permalink' : ''\">\n</span>\n<span class=\"hint-flash\" :text=\"document.body.dataset.flash || ''\">\n</span>\n</div>\n<dialog id=\"panel-help\" class=\"panel modal\" aria-label=\"Keyboard shortcuts\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<h2>Keyboard shortcuts</h2>\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd> close</button>\n</div>\n<div class=\"keys-pref\">\n<label>\n<input type=\"checkbox\" id=\"keys-off\" aria-describedby=\"keys-note\" hx-on:change=\"ermite.setKeysOff(this.checked)\"> Turn off single-key shortcuts</label>\n<p id=\"keys-note\" class=\"dim\">Single-key shortcuts are on. ctrl k and esc work whatever this says.</p>\n</div>\n<dl class=\"keys\">\n<div>\n<dt>\n<kbd>ctrl k</kbd>\n<kbd>:</kbd>\n</dt>\n<dd>go to a section, branch, tag, file or repository</dd>\n</div>\n<div>\n<dt>\n<kbd>?</kbd>\n</dt>\n<dd>this list</dd>\n</div>\n<div>\n<dt>\n<kbd>j</kbd>\n<kbd>k</kbd>\n</dt>\n<dd>move the row cursor down / up</dd>\n</div>\n<div>\n<dt>\n<kbd>enter</kbd>\n</dt>\n<dd>open the row under the cursor; on Files, a directory opens or closes in place</dd>\n</div>\n<div>\n<dt>\n<kbd>↑</kbd>\n<kbd>↓</kbd>\n<kbd>←</kbd>\n<kbd>→</kbd>\n<kbd>home</kbd>\n<kbd>end</kbd>\n</dt>\n<dd>in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file</dd>\n</div>\n<div>\n<dt>\n<kbd>l</kbd>\n<kbd>h</kbd>\n</dt>\n<dd>on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls</dd>\n</div>\n<div>\n<dt>\n<kbd>g g</kbd>\n<kbd>G</kbd>\n</dt>\n<dd>first / last row</dd>\n</div>\n<div>\n<dt>\n<kbd>/</kbd>\n</dt>\n<dd>filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)</dd>\n</div>\n<div>\n<dt>\n<kbd>b</kbd>\n</dt>\n<dd>switch branch or tag</dd>\n</div>\n<div>\n<dt>\n<kbd>s</kbd>\n<kbd>t</kbd>\n<kbd>c</kbd>\n<kbd>r</kbd>\n<kbd>m</kbd>\n<kbd>i</kbd>\n</dt>\n<dd>tabs: summary, files, commits, branches & tags, merge requests, issues</dd>\n</div>\n<div>\n<dt>\n<kbd>g h</kbd>\n</dt>\n<dd>home</dd>\n</div>\n<div>\n<dt>\n<kbd>w</kbd>\n</dt>\n<dd>wide mode: use the whole width of the screen, or not (remembered)</dd>\n</div>\n<div>\n<dt>\n<kbd>y</kbd>\n</dt>\n<dd>copy a permalink pinned to the commit</dd>\n</div>\n<div>\n<dt>\n<kbd>d</kbd>\n<kbd>u</kbd>\n<kbd>x</kbd>\n</dt>\n<dd>diff: split / unified / collapse or expand all</dd>\n</div>\n<div>\n<dt>\n<kbd>e</kbd>\n<kbd>E</kbd>\n</dt>\n<dd>diff: the whole file in view / every file, with the lines the hunks hide</dd>\n</div>\n<div>\n<dt>\n<kbd>n</kbd>\n</dt>\n<dd>merge request: next note in the diff</dd>\n</div>\n<div>\n<dt>\n<kbd>esc</kbd>\n</dt>\n<dd>close a dialog, leave a field</dd>\n</div>\n</dl>\n</dialog>\n<dialog id=\"panel-refs\" class=\"panel modal\" aria-label=\"Switch ref\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<label for=\"refs-filter\" class=\"sr\">filter branches and tags</label>\n<input id=\"refs-filter\" type=\"search\" placeholder=\"Switch branch or tag…\" autocomplete=\"off\" data-pick=\"#panel-refs li\" hx-on:input=\"ermite.filter(this)\">\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd>\n</button>\n</div>\n<div class=\"panel-cols\" data-picklist>\n<section aria-label=\"Branches\">\n<h2>Branches <span class=\"count\">2</span>\n</h2>\n<ul>\n<li>\n<a href=\"/files/tree/feature/x\">\n<span class=\"mark\" aria-hidden=\"true\"> </span>feature/x</a>\n</li>\n<li>\n<a href=\"/files/tree/main\" aria-current=\"true\">\n<span class=\"mark\" aria-hidden=\"true\">●</span>main</a>\n</li>\n</ul>\n</section>\n<section aria-label=\"Tags\">\n<h2>Tags <span class=\"count\">1</span>\n</h2>\n<ul>\n<li>\n<a href=\"/files/tree/v1.0\">\n<span class=\"mark\" aria-hidden=\"true\"> </span>v1.0</a>\n</li>\n</ul>\n</section>\n</div>\n</dialog>\n<dialog id=\"panel-cmd\" class=\"panel modal\" aria-label=\"Go to\" hx-on:close=\"ermiteFinder.paletteClose()\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<label for=\"cmd-q\" class=\"sr\">go to</label>\n<input id=\"cmd-q\" type=\"search\" placeholder=\"Go to a section, branch, tag, file or repository…\" autocomplete=\"off\" spellcheck=\"false\" role=\"combobox\" aria-autocomplete=\"list\" aria-expanded=\"true\" aria-controls=\"cmd-list\" aria-activedescendant=\"cmd-o0\" hx-on:input=\"ermite.cmdFilter(this); ermiteFinder.palette(this)\" hx-on:keydown=\"ermite.cmdKey(event)\">\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd>\n</button>\n</div>\n<ul id=\"cmd-list\" class=\"cmd-list\" role=\"listbox\" aria-label=\"Targets\">\n<li id=\"cmd-o0\" role=\"option\" aria-selected=\"true\" data-k=\"go home\" data-cursor>\n<a href=\"/\" tabindex=\"-1\">\n<span class=\"lbl\">home</span>\n<span class=\"k\">go</span>\n</a>\n</li>\n<li id=\"cmd-o1\" role=\"option\" aria-selected=\"false\" data-k=\"section summary\">\n<a href=\"/files\" tabindex=\"-1\">\n<span class=\"lbl\">summary</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o2\" role=\"option\" aria-selected=\"false\" data-k=\"section files\">\n<a href=\"/files/tree/main\" tabindex=\"-1\">\n<span class=\"lbl\">files</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o3\" role=\"option\" aria-selected=\"false\" data-k=\"section commits\">\n<a href=\"/files/commits/main\" tabindex=\"-1\">\n<span class=\"lbl\">commits</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o4\" role=\"option\" aria-selected=\"false\" data-k=\"section branches & tags\">\n<a href=\"/files/refs\" tabindex=\"-1\">\n<span class=\"lbl\">branches & tags</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o5\" role=\"option\" aria-selected=\"false\" data-k=\"section merge requests\">\n<a href=\"/files/merge-requests\" tabindex=\"-1\">\n<span class=\"lbl\">merge requests</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o6\" role=\"option\" aria-selected=\"false\" data-k=\"section actions\">\n<a href=\"/files/actions\" tabindex=\"-1\">\n<span class=\"lbl\">actions</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o7\" role=\"option\" aria-selected=\"false\" data-k=\"branch feature/x\">\n<a href=\"/files/tree/feature/x\" tabindex=\"-1\">\n<span class=\"lbl\">feature/x</span>\n<span class=\"k\">branch</span>\n</a>\n</li>\n<li id=\"cmd-o8\" role=\"option\" aria-selected=\"false\" data-k=\"branch main\">\n<a href=\"/files/tree/main\" tabindex=\"-1\">\n<span class=\"lbl\">main</span>\n<span class=\"k\">branch</span>\n</a>\n</li>\n<li id=\"cmd-o9\" role=\"option\" aria-selected=\"false\" data-k=\"tag v1.0\">\n<a href=\"/files/tree/v1.0\" tabindex=\"-1\">\n<span class=\"lbl\">v1.0</span>\n<span class=\"k\">tag</span>\n</a>\n</li>\n<li id=\"cmd-o10\" role=\"option\" aria-selected=\"false\" data-k=\"action turn single-key shortcuts on off keyboard\">\n<a href=\"#\" data-fire=\"keys\" tabindex=\"-1\">\n<span class=\"lbl\">turn single-key shortcuts off</span>\n<span class=\"k\">action</span>\n</a>\n</li>\n</ul>\n<p class=\"panel-foot\">\n<span>\n<kbd>↑</kbd>\n<kbd>↓</kbd> move</span>\n<span>\n<kbd>enter</kbd> open</span>\n<span>\n<kbd>esc</kbd> close</span>\n</p>\n</dialog>\n<div id=\"keys\" hidden hx-on=\"k-j from:body -> ermite.move(1);\n k-k from:body -> ermite.move(-1);\n k-top from:body -> ermite.edge(false);\n k-bottom from:body -> ermite.edge(true);\n k-open from:body -> ermite.open();\n k-right from:body -> ermite.rail(true);\n k-left from:body -> ermite.rail(false);\n k-esc from:body -> ermite.closeDialogs();\n k-help from:body -> ermite.dialog('panel-help');\n k-refs from:body -> ermite.dialog('panel-refs', 'refs-filter');\n k-cmd from:body -> ermite.dialog('panel-cmd', 'cmd-q'); ermiteFinder.load();\n k-filter from:body -> ermite.focusFilter();\n k-gh from:body -> ermite.go('.brand');\n k-s from:body -> ermite.tab('s');\n k-t from:body -> ermite.tab('t');\n k-c from:body -> ermite.tab('c');\n k-r from:body -> ermite.tab('r');\n k-m from:body -> ermite.tab('m');\n k-i from:body -> ermite.tab('i');\n k-next from:body -> ermite.nextNote();\n k-split from:body -> ermite.layout('split');\n k-unified from:body -> ermite.layout('unified');\n k-collapse from:body -> ermite.collapse();\n k-wide from:body -> window.ermiteWide.toggle();\n k-expand from:body -> ermite.expandFile();\n k-expandAll from:body -> ermite.expandAll();\n k-permalink from:body -> ermite.permalink();\n k-merge from:body -> window.ermiteMR?.openMerge();\n k-read from:body -> window.ermiteMR?.markRead();\n k-gf from:body -> window.ermiteMR?.focusFiles();\n k-keys from:body -> ermite.toggleKeys()\">\n</div>\n</body>\n</html>\n"
- actual : "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<meta name=\"color-scheme\" content=\"light dark\">\n<title>docs/guide.md · files · example.test</title>\n<meta name=\"theme-color\" media=\"(prefers-color-scheme: light)\" content=\"#ffffff\">\n<meta name=\"theme-color\" media=\"(prefers-color-scheme: dark)\" content=\"#0c0c0c\">\n<meta name=\"apple-mobile-web-app-title\" content=\"ermite\">\n<link rel=\"icon\" type=\"image/svg+xml\" href=\"/-/static/img/icon.HASH.svg\">\n<link rel=\"apple-touch-icon\" href=\"/-/static/app/apple-touch-icon.HASH.png\">\n<link rel=\"manifest\" href=\"/-/static/app/manifest.HASH.webmanifest\">\n<link rel=\"preload\" href=\"/-/static/fonts/atkinson-next.HASH.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<link rel=\"stylesheet\" href=\"/-/static/css/ermite.HASH.css\">\n<meta name=\"htmx-config\" content='{\"history\":false,\"includeIndicatorCSS\":false,\"extensions\":\"sse, hx-live\"}'>\n<script src=\"/-/static/js/htmx.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/hx-live.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/hx-sse.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/store.HASH.js\">\n</script>\n<script src=\"/-/static/js/ermite.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/files.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/passkey.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/log.HASH.js\" defer>\n</script>\n</head>\n<body data-ref=\"main\" data-sha=\"SHA40\" data-sel=\"\" data-nav=\"\" data-paths=\"/files/paths/SHA40\" data-blob=\"/files/blob/main\">\n<a class=\"skip\" href=\"#main\">skip to content</a>\n<header class=\"hdr\">\n<div class=\"hdr-top\">\n<a class=\"brand\" href=\"/\" data-g=\"h\" aria-label=\"home\" title=\"home (g h)\">\n<span class=\"brand-mark\" aria-hidden=\"true\">\n</span>\n</a>\n<nav class=\"crumbs\" aria-label=\"Path\">\n<ol>\n<li>\n<a href=\"/files\">files</a>\n</li>\n<li>\n<a href=\"/files/tree/main\">blob</a>\n</li>\n<li>\n<a href=\"/files/tree/main\">main</a>\n</li>\n<li>\n<a href=\"/files/tree/main/docs\">docs</a>\n</li>\n<li>\n<a href=\"/files/blob/main/docs/guide.md\" aria-current=\"page\">guide.md</a>\n</li>\n</ol>\n</nav>\n<div class=\"hdr-acts\">\n<a class=\"btn ref\" href=\"/files/refs\" data-fire=\"refs\" aria-keyshortcuts=\"b\" title=\"switch branch or tag (b)\">\n<span class=\"ico i-branch\" aria-hidden=\"true\">\n</span>\n<span class=\"ref-name\">main</span>\n<span class=\"sha\">SHA7</span>\n</a>\n<button type=\"button\" class=\"btn search\" data-js aria-haspopup=\"dialog\" aria-controls=\"panel-cmd\" aria-keyshortcuts=\"Control+K :\" title=\"go to a section, ref, file or repo (ctrl k or :)\" data-fire=\"cmd\">\n<span class=\"ico i-search\" aria-hidden=\"true\">\n</span>\n<span class=\"search-label\">Go to…</span>\n<kbd aria-hidden=\"true\">ctrl k</kbd>\n</button>\n</div>\n</div>\n<nav class=\"tabs\" aria-label=\"Sections\">\n<ul>\n<li>\n<a href=\"/files\" data-key=\"s\" aria-keyshortcuts=\"s\">Summary <kbd aria-hidden=\"true\">s</kbd>\n</a>\n</li>\n<li>\n<a href=\"/files/tree/main\" data-key=\"t\" aria-keyshortcuts=\"t\" aria-current=\"page\">Files <kbd aria-hidden=\"true\">t</kbd>\n</a>\n</li>\n<li>\n<a href=\"/files/commits/main\" data-key=\"c\" aria-keyshortcuts=\"c\">Commits <kbd aria-hidden=\"true\">c</kbd>\n</a>\n</li>\n<li>\n<a href=\"/files/refs\" data-key=\"r\" aria-keyshortcuts=\"r\">Branches & tags <kbd aria-hidden=\"true\">r</kbd>\n</a>\n</li>\n<li>\n<a href=\"/files/merge-requests\" data-key=\"m\" aria-keyshortcuts=\"m\">Merge requests <kbd aria-hidden=\"true\">m</kbd>\n</a>\n</li>\n<li>\n<a href=\"/files/actions\" data-key=\"a\" aria-keyshortcuts=\"a\">Actions <kbd aria-hidden=\"true\">a</kbd>\n</a>\n</li>\n</ul>\n</nav>\n</header>\n<div class=\"work has-rail\">\n<main id=\"main\" tabindex=\"-1\">\n<h1 class=\"file-h\">\n<span>guide.md</span>\n<span class=\"acts\">\n<a class=\"btn\" href=\"/files/raw/main/docs/guide.md\">Raw</a>\n<a class=\"btn\" href=\"/files/commits/main/docs/guide.md\">History</a>\n<a class=\"btn\" href=\"/files/tree/main/docs\">Folder</a>\n</span>\n</h1>\n<article class=\"prose\" aria-label=\"guide.md\" hx-ignore>\n<h1 id=\"md-guide\">Guide</h1>\n<h2 id=\"md-steps\">Steps</h2>\n<p>Run it.</p>\n<pre class=\"chroma\">\n<code class=\"language-sh\">make all\n</code>\n</pre>\n</article>\n<details class=\"source\">\n<summary>source</summary>\n<pre class=\"chroma code\" data-anchor=\"\" hx-on:click=\"let a = event.target.closest('a.ln'); if (!a) return; event.preventDefault();\n let n = +a.textContent; if (!event.shiftKey || !data.anchor) data.anchor = n;\n let lo = Math.min(+data.anchor, n), hi = Math.max(+data.anchor, n);\n history.replaceState(null, '', '#L' + lo + (hi > lo ? '-L' + hi : '')); trigger('sel')\" hx-on:sel=\"let m = location.hash.match(/^#L(\\d+)(?:-L(\\d+))?$/); let lo = m ? +m[1] : 0, hi = m ? +(m[2] || m[1]) : 0;\n q('.line in this').arr().forEach(l => { let k = +l.id.slice(1); l.classList.toggle('sel', k >= lo && k <= hi) });\n document.body.dataset.sel = lo ? 'L' + lo + (hi > lo ? '-L' + hi + ' · ' + (hi - lo + 1) + ' lines' : '') : '';\n if (lo && event.detail?.scroll) document.getElementById('L' + lo)?.scrollIntoView({ block: 'center' })\" hx-live=\"if (!data.ready) { data.ready = '1'; trigger('sel', { scroll: true }) }\" data-ready=\"\">\n<code hx-ignore>\n<span class=\"line\" id=\"L1\">\n<a class=\"ln\" href=\"#L1\">1</a>\n<span class=\"gh\"># Guide</span>\n</span>\n<span class=\"line\" id=\"L2\">\n<a class=\"ln\" href=\"#L2\">2</a>\n</span>\n<span class=\"line\" id=\"L3\">\n<a class=\"ln\" href=\"#L3\">3</a>\n<span class=\"gu\">## Steps</span>\n</span>\n<span class=\"line\" id=\"L4\">\n<a class=\"ln\" href=\"#L4\">4</a>\n</span>\n<span class=\"line\" id=\"L5\">\n<a class=\"ln\" href=\"#L5\">5</a>Run it.</span>\n<span class=\"line\" id=\"L6\">\n<a class=\"ln\" href=\"#L6\">6</a>\n</span>\n<span class=\"line\" id=\"L7\">\n<a class=\"ln\" href=\"#L7\">7</a>\n<span class=\"s\">```sh</span>\n</span>\n<span class=\"line\" id=\"L8\">\n<a class=\"ln\" href=\"#L8\">8</a>make all</span>\n<span class=\"line\" id=\"L9\">\n<a class=\"ln\" href=\"#L9\">9</a>\n<span class=\"s\">```</span>\n</span>\n</code>\n</pre>\n</details>\n</main>\n<aside class=\"rail\" aria-label=\"Context\">\n<section aria-labelledby=\"r-file\">\n<h2 id=\"r-file\">File</h2>\n<dl class=\"kv\">\n<dt>size</dt>\n<dd>47 B</dd>\n<dt>lines</dt>\n<dd>9</dd>\n<dt>type</dt>\n<dd>markdown</dd>\n</dl>\n</section>\n<section aria-labelledby=\"r-last\">\n<h2 id=\"r-last\">Last change <a href=\"/files/commits/main/docs/guide.md\">History</a>\n</h2>\n<p>\n<a href=\"/files/commit/SHA40\">SHA7</a> add docs/guide.md</p>\n<p class=\"dim\">T · <time datetime=\"STAMP\" title=\"STAMP\">AGO</time>\n</p>\n</section>\n<section aria-labelledby=\"r-outline\">\n<h2 id=\"r-outline\">On this page</h2>\n<nav class=\"outline\" aria-label=\"Outline\">\n<a class=\"l1\" href=\"#md-guide\">Guide</a>\n<a class=\"l2\" href=\"#md-steps\">Steps</a>\n</nav>\n</section>\n<section aria-labelledby=\"r-sel\">\n<h2 id=\"r-sel\">Selection</h2>\n<p :text=\"document.body.dataset.sel || 'none · click a line number, shift-click extends'\">none · click a line number, shift-click extends</p>\n<p class=\"dim\">y copies a permalink pinned to the commit sha</p>\n</section>\n</aside>\n</div>\n<footer class=\"foot\">\n<span>ermite devel</span>\n<a href=\"http://example.test/ermite\" rel=\"noopener\" title=\"source of this version (AGPL-3.0-or-later)\">source</a>\n<button type=\"button\" class=\"foot-keys\" data-js data-fire=\"help\" aria-haspopup=\"dialog\" aria-controls=\"panel-help\" aria-keyshortcuts=\"?\">\n<kbd aria-hidden=\"true\">?</kbd> keyboard shortcuts</button>\n</footer>\n<div class=\"hint\" role=\"status\" aria-live=\"polite\">\n<span class=\"hint-nav\" :text=\"document.body.dataset.nav || ''\">\n</span>\n<span class=\"hint-sel\" :text=\"document.body.dataset.sel ? document.body.dataset.sel + ' · y permalink' : ''\">\n</span>\n<span class=\"hint-flash\" :text=\"document.body.dataset.flash || ''\">\n</span>\n</div>\n<dialog id=\"panel-help\" class=\"panel modal\" aria-label=\"Keyboard shortcuts\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<h2>Keyboard shortcuts</h2>\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd> close</button>\n</div>\n<div class=\"keys-pref\">\n<label>\n<input type=\"checkbox\" id=\"keys-off\" aria-describedby=\"keys-note\" hx-on:change=\"ermite.setKeysOff(this.checked)\"> Turn off single-key shortcuts</label>\n<p id=\"keys-note\" class=\"dim\">Single-key shortcuts are on. ctrl k and esc work whatever this says.</p>\n</div>\n<dl class=\"keys\">\n<div>\n<dt>\n<kbd>ctrl k</kbd>\n<kbd>:</kbd>\n</dt>\n<dd>go to a section, branch, tag, file or repository</dd>\n</div>\n<div>\n<dt>\n<kbd>?</kbd>\n</dt>\n<dd>this list</dd>\n</div>\n<div>\n<dt>\n<kbd>j</kbd>\n<kbd>k</kbd>\n</dt>\n<dd>move the row cursor down / up</dd>\n</div>\n<div>\n<dt>\n<kbd>enter</kbd>\n</dt>\n<dd>open the row under the cursor; on Files, a directory opens or closes in place</dd>\n</div>\n<div>\n<dt>\n<kbd>↑</kbd>\n<kbd>↓</kbd>\n<kbd>←</kbd>\n<kbd>→</kbd>\n<kbd>home</kbd>\n<kbd>end</kbd>\n</dt>\n<dd>in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file</dd>\n</div>\n<div>\n<dt>\n<kbd>l</kbd>\n<kbd>h</kbd>\n</dt>\n<dd>on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls</dd>\n</div>\n<div>\n<dt>\n<kbd>g g</kbd>\n<kbd>G</kbd>\n</dt>\n<dd>first / last row</dd>\n</div>\n<div>\n<dt>\n<kbd>/</kbd>\n</dt>\n<dd>filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)</dd>\n</div>\n<div>\n<dt>\n<kbd>b</kbd>\n</dt>\n<dd>switch branch or tag</dd>\n</div>\n<div>\n<dt>\n<kbd>s</kbd>\n<kbd>t</kbd>\n<kbd>c</kbd>\n<kbd>r</kbd>\n<kbd>m</kbd>\n<kbd>i</kbd>\n</dt>\n<dd>tabs: summary, files, commits, branches & tags, merge requests, issues</dd>\n</div>\n<div>\n<dt>\n<kbd>g h</kbd>\n</dt>\n<dd>home</dd>\n</div>\n<div>\n<dt>\n<kbd>w</kbd>\n</dt>\n<dd>wide mode: use the whole width of the screen, or not (remembered)</dd>\n</div>\n<div>\n<dt>\n<kbd>y</kbd>\n</dt>\n<dd>copy a permalink pinned to the commit</dd>\n</div>\n<div>\n<dt>\n<kbd>d</kbd>\n<kbd>u</kbd>\n<kbd>x</kbd>\n</dt>\n<dd>diff: split / unified / collapse or expand all</dd>\n</div>\n<div>\n<dt>\n<kbd>e</kbd>\n<kbd>E</kbd>\n</dt>\n<dd>diff: the whole file in view / every file, with the lines the hunks hide</dd>\n</div>\n<div>\n<dt>\n<kbd>n</kbd>\n</dt>\n<dd>merge request: next note in the diff</dd>\n</div>\n<div>\n<dt>\n<kbd>esc</kbd>\n</dt>\n<dd>close a dialog, leave a field</dd>\n</div>\n</dl>\n</dialog>\n<dialog id=\"panel-refs\" class=\"panel modal\" aria-label=\"Switch ref\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<label for=\"refs-filter\" class=\"sr\">filter branches and tags</label>\n<input id=\"refs-filter\" type=\"search\" placeholder=\"Switch branch or tag…\" autocomplete=\"off\" data-pick=\"#panel-refs li\" hx-on:input=\"ermite.filter(this)\">\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd>\n</button>\n</div>\n<div class=\"panel-cols\" data-picklist>\n<section aria-label=\"Branches\">\n<h2>Branches <span class=\"count\">2</span>\n</h2>\n<ul>\n<li>\n<a href=\"/files/tree/feature/x\">\n<span class=\"mark\" aria-hidden=\"true\"> </span>feature/x</a>\n</li>\n<li>\n<a href=\"/files/tree/main\" aria-current=\"true\">\n<span class=\"mark\" aria-hidden=\"true\">●</span>main</a>\n</li>\n</ul>\n</section>\n<section aria-label=\"Tags\">\n<h2>Tags <span class=\"count\">1</span>\n</h2>\n<ul>\n<li>\n<a href=\"/files/tree/v1.0\">\n<span class=\"mark\" aria-hidden=\"true\"> </span>v1.0</a>\n</li>\n</ul>\n</section>\n</div>\n</dialog>\n<dialog id=\"panel-cmd\" class=\"panel modal\" aria-label=\"Go to\" hx-on:close=\"ermiteFinder.paletteClose()\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<label for=\"cmd-q\" class=\"sr\">go to</label>\n<input id=\"cmd-q\" type=\"search\" placeholder=\"Go to a section, branch, tag, file or repository…\" autocomplete=\"off\" spellcheck=\"false\" role=\"combobox\" aria-autocomplete=\"list\" aria-expanded=\"true\" aria-controls=\"cmd-list\" aria-activedescendant=\"cmd-o0\" hx-on:input=\"ermite.cmdFilter(this); ermiteFinder.palette(this)\" hx-on:keydown=\"ermite.cmdKey(event)\">\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd>\n</button>\n</div>\n<ul id=\"cmd-list\" class=\"cmd-list\" role=\"listbox\" aria-label=\"Targets\">\n<li id=\"cmd-o0\" role=\"option\" aria-selected=\"true\" data-k=\"go home\" data-cursor>\n<a href=\"/\" tabindex=\"-1\">\n<span class=\"lbl\">home</span>\n<span class=\"k\">go</span>\n</a>\n</li>\n<li id=\"cmd-o1\" role=\"option\" aria-selected=\"false\" data-k=\"section summary\">\n<a href=\"/files\" tabindex=\"-1\">\n<span class=\"lbl\">summary</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o2\" role=\"option\" aria-selected=\"false\" data-k=\"section files\">\n<a href=\"/files/tree/main\" tabindex=\"-1\">\n<span class=\"lbl\">files</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o3\" role=\"option\" aria-selected=\"false\" data-k=\"section commits\">\n<a href=\"/files/commits/main\" tabindex=\"-1\">\n<span class=\"lbl\">commits</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o4\" role=\"option\" aria-selected=\"false\" data-k=\"section branches & tags\">\n<a href=\"/files/refs\" tabindex=\"-1\">\n<span class=\"lbl\">branches & tags</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o5\" role=\"option\" aria-selected=\"false\" data-k=\"section merge requests\">\n<a href=\"/files/merge-requests\" tabindex=\"-1\">\n<span class=\"lbl\">merge requests</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o6\" role=\"option\" aria-selected=\"false\" data-k=\"section actions\">\n<a href=\"/files/actions\" tabindex=\"-1\">\n<span class=\"lbl\">actions</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o7\" role=\"option\" aria-selected=\"false\" data-k=\"branch feature/x\">\n<a href=\"/files/tree/feature/x\" tabindex=\"-1\">\n<span class=\"lbl\">feature/x</span>\n<span class=\"k\">branch</span>\n</a>\n</li>\n<li id=\"cmd-o8\" role=\"option\" aria-selected=\"false\" data-k=\"branch main\">\n<a href=\"/files/tree/main\" tabindex=\"-1\">\n<span class=\"lbl\">main</span>\n<span class=\"k\">branch</span>\n</a>\n</li>\n<li id=\"cmd-o9\" role=\"option\" aria-selected=\"false\" data-k=\"tag v1.0\">\n<a href=\"/files/tree/v1.0\" tabindex=\"-1\">\n<span class=\"lbl\">v1.0</span>\n<span class=\"k\">tag</span>\n</a>\n</li>\n<li id=\"cmd-o10\" role=\"option\" aria-selected=\"false\" data-k=\"action turn single-key shortcuts on off keyboard\">\n<a href=\"#\" data-fire=\"keys\" tabindex=\"-1\">\n<span class=\"lbl\">turn single-key shortcuts off</span>\n<span class=\"k\">action</span>\n</a>\n</li>\n</ul>\n<p class=\"panel-foot\">\n<span>\n<kbd>↑</kbd>\n<kbd>↓</kbd> move</span>\n<span>\n<kbd>enter</kbd> open</span>\n<span>\n<kbd>esc</kbd> close</span>\n</p>\n</dialog>\n<div id=\"keys\" hidden hx-on=\"k-j from:body -> ermite.move(1);\n k-k from:body -> ermite.move(-1);\n k-top from:body -> ermite.edge(false);\n k-bottom from:body -> ermite.edge(true);\n k-open from:body -> ermite.open();\n k-right from:body -> ermite.rail(true);\n k-left from:body -> ermite.rail(false);\n k-esc from:body -> ermite.closeDialogs();\n k-help from:body -> ermite.dialog('panel-help');\n k-refs from:body -> ermite.dialog('panel-refs', 'refs-filter');\n k-cmd from:body -> ermite.dialog('panel-cmd', 'cmd-q'); ermiteFinder.load();\n k-filter from:body -> ermite.focusFilter();\n k-gh from:body -> ermite.go('.brand');\n k-s from:body -> ermite.tab('s');\n k-t from:body -> ermite.tab('t');\n k-c from:body -> ermite.tab('c');\n k-r from:body -> ermite.tab('r');\n k-m from:body -> ermite.tab('m');\n k-i from:body -> ermite.tab('i');\n k-next from:body -> ermite.nextNote();\n k-split from:body -> ermite.layout('split');\n k-unified from:body -> ermite.layout('unified');\n k-collapse from:body -> ermite.collapse();\n k-wide from:body -> window.ermiteWide.toggle();\n k-expand from:body -> ermite.expandFile();\n k-expandAll from:body -> ermite.expandAll();\n k-permalink from:body -> ermite.permalink();\n k-merge from:body -> window.ermiteMR?.openMerge();\n k-read from:body -> window.ermiteMR?.markRead();\n k-gf from:body -> window.ermiteMR?.focusFiles();\n k-keys from:body -> ermite.toggleKeys()\">\n</div>\n</body>\n</html>\n"
- Diff:
- --- Expected
- +++ Actual
- @@ -118,3 +118,3 @@
- <p>Run it.</p>
- -<pre>
- +<pre class="chroma">
- <code class="language-sh">make all
- Test: TestWebFilesGolden/blob-markdown
- Messages: blob-markdown
- --- FAIL: TestWebGolden (0.96s)
- --- FAIL: TestWebGolden/summary (0.07s)
- web_test.go:130:
- Error Trace: /__w/ermite/ermite/internal/app/web_test.go:104
- /__w/ermite/ermite/internal/app/web_test.go:130
- Error: Not equal:
- expected: "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<meta name=\"color-scheme\" content=\"light dark\">\n<title>demo · example.test</title>\n<meta name=\"theme-color\" media=\"(prefers-color-scheme: light)\" content=\"#ffffff\">\n<meta name=\"theme-color\" media=\"(prefers-color-scheme: dark)\" content=\"#0c0c0c\">\n<meta name=\"apple-mobile-web-app-title\" content=\"ermite\">\n<link rel=\"icon\" type=\"image/svg+xml\" href=\"/-/static/img/icon.HASH.svg\">\n<link rel=\"apple-touch-icon\" href=\"/-/static/app/apple-touch-icon.HASH.png\">\n<link rel=\"manifest\" href=\"/-/static/app/manifest.HASH.webmanifest\">\n<link rel=\"preload\" href=\"/-/static/fonts/atkinson-next.HASH.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<link rel=\"stylesheet\" href=\"/-/static/css/ermite.HASH.css\">\n<meta name=\"htmx-config\" content='{\"history\":false,\"includeIndicatorCSS\":false,\"extensions\":\"sse, hx-live\"}'>\n<script src=\"/-/static/js/htmx.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/hx-live.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/hx-sse.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/store.HASH.js\">\n</script>\n<script src=\"/-/static/js/ermite.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/files.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/passkey.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/log.HASH.js\" defer>\n</script>\n</head>\n<body data-ref=\"main\" data-sha=\"SHA40\" data-sel=\"\" data-nav=\"\" data-paths=\"/demo/paths/SHA40\" data-blob=\"/demo/blob/main\">\n<a class=\"skip\" href=\"#main\">skip to content</a>\n<header class=\"hdr\">\n<div class=\"hdr-top\">\n<a class=\"brand\" href=\"/\" data-g=\"h\" aria-label=\"home\" title=\"home (g h)\">\n<span class=\"brand-mark\" aria-hidden=\"true\">\n</span>\n</a>\n<nav class=\"crumbs\" aria-label=\"Path\">\n<ol>\n<li>\n<a href=\"/demo\" aria-current=\"page\">demo</a>\n</li>\n</ol>\n</nav>\n<div class=\"hdr-acts\">\n<a class=\"btn ref\" href=\"/demo/refs\" data-fire=\"refs\" aria-keyshortcuts=\"b\" title=\"switch branch or tag (b)\">\n<span class=\"ico i-branch\" aria-hidden=\"true\">\n</span>\n<span class=\"ref-name\">main</span>\n<span class=\"sha\">SHA7</span>\n</a>\n<button type=\"button\" class=\"btn search\" data-js aria-haspopup=\"dialog\" aria-controls=\"panel-cmd\" aria-keyshortcuts=\"Control+K :\" title=\"go to a section, ref, file or repo (ctrl k or :)\" data-fire=\"cmd\">\n<span class=\"ico i-search\" aria-hidden=\"true\">\n</span>\n<span class=\"search-label\">Go to…</span>\n<kbd aria-hidden=\"true\">ctrl k</kbd>\n</button>\n</div>\n</div>\n<nav class=\"tabs\" aria-label=\"Sections\">\n<ul>\n<li>\n<a href=\"/demo\" data-key=\"s\" aria-keyshortcuts=\"s\" aria-current=\"page\">Summary <kbd aria-hidden=\"true\">s</kbd>\n</a>\n</li>\n<li>\n<a href=\"/demo/tree/main\" data-key=\"t\" aria-keyshortcuts=\"t\">Files <kbd aria-hidden=\"true\">t</kbd>\n</a>\n</li>\n<li>\n<a href=\"/demo/commits/main\" data-key=\"c\" aria-keyshortcuts=\"c\">Commits <kbd aria-hidden=\"true\">c</kbd>\n</a>\n</li>\n<li>\n<a href=\"/demo/refs\" data-key=\"r\" aria-keyshortcuts=\"r\">Branches & tags <kbd aria-hidden=\"true\">r</kbd>\n</a>\n</li>\n<li>\n<a href=\"/demo/merge-requests\" data-key=\"m\" aria-keyshortcuts=\"m\">Merge requests <kbd aria-hidden=\"true\">m</kbd>\n</a>\n</li>\n<li>\n<a href=\"/demo/actions\" data-key=\"a\" aria-keyshortcuts=\"a\">Actions <kbd aria-hidden=\"true\">a</kbd>\n</a>\n</li>\n</ul>\n</nav>\n</header>\n<div class=\"work has-rail\">\n<section class=\"work-lede\" aria-label=\"Description\">\n<p class=\"lede\">A demo repository</p>\n</section>\n<main id=\"main\" tabindex=\"-1\">\n<section class=\"card readme\" aria-labelledby=\"readme-h\">\n<h2 class=\"card-h\" id=\"readme-h\">\n<span class=\"ico i-file\" aria-hidden=\"true\">\n</span> README.md</h2>\n<article class=\"prose\" aria-label=\"README.md\" hx-ignore>\n<h1 id=\"md-demo\">Demo</h1>\n<p>A small <em>demo</em> with a <a href=\"/demo/blob/main/docs/guide.md\">guide</a> and <a href=\"https://example.org/x\" rel=\"nofollow noopener noreferrer\">the site</a>.</p>\n<h2 id=\"md-install\">Install</h2>\n<pre>\n<code class=\"language-sh\">go install example.org/demo@latest\n</code>\n</pre>\n<h2 id=\"md-usage\">Usage</h2>\n<table>\n<thead>\n<tr>\n<th>a</th>\n<th align=\"right\">b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td align=\"right\">2</td>\n</tr>\n</tbody>\n</table>\n</article>\n</section>\n</main>\n<aside class=\"rail\" aria-label=\"Context\">\n<section aria-labelledby=\"r-clone\">\n<h2 id=\"r-clone\">Clone</h2>\n<div class=\"clone\" id=\"clone-demo\">\n<div class=\"clone-line\">\n<span class=\"mute\" aria-hidden=\"true\">$ </span>\n<code>git clone http://example.test/demo.git</code>\n<button type=\"button\" class=\"btn copy\" data-js data-label=\"Copy\" aria-label=\"copy: git clone http://example.test/demo.git\" hx-on:click=\"ermite.copy(this)\">Copy</button>\n</div>\n</div>\n</section>\n<section aria-labelledby=\"r-facts\">\n<h2 id=\"r-facts\">About</h2>\n<dl class=\"kv\">\n<dt>last push</dt>\n<dd id=\"last-push-demo\">\n<time datetime=\"STAMP\">AGO · STAMP</time>\n</dd>\n<dt>branch</dt>\n<dd>main · 2 branches</dd>\n<dt>created</dt>\n<dd>\n<time datetime=\"STAMP\">STAMP</time>\n</dd>\n<dt>latest tag</dt>\n<dd class=\"latest-tag\">\n<a class=\"tag-name\" href=\"/demo/tree/v0.2.0\" title=\"add main.go\">v0.2.0</a> · <time datetime=\"STAMP\" title=\"STAMP\">AGO</time> · <a class=\"all-tags\" href=\"/demo/refs\">2 tags</a>\n</dd>\n</dl>\n</section>\n<section aria-labelledby=\"r-recent\">\n<h2 id=\"r-recent\">Recent commits <a href=\"/demo/commits/main\">View all</a>\n</h2>\n<table class=\"list commits\" aria-label=\"Commits\">\n<tbody data-rows>\n<tr data-cursor>\n<td class=\"c-sha mute\">SHA7</td>\n<td class=\"c-subject\">\n<a href=\"/demo/commit/SHA40\">add main.go</a>\n<span class=\"pill\">main</span>\n<span class=\"pill tag\">\n<span class=\"sr\">tag </span>v0.2.0</span>\n</td>\n<td class=\"c-ck\">\n</td>\n<td class=\"c-who dim\">T</td>\n<td class=\"c-when nowrap dim\">\n<time datetime=\"STAMP\" title=\"STAMP\">AGO</time>\n</td>\n</tr>\n<tr>\n<td class=\"c-sha mute\">SHA7</td>\n<td class=\"c-subject\">\n<a href=\"/demo/commit/SHA40\">first commit</a>\n<span class=\"pill tag\">\n<span class=\"sr\">tag </span>v0.1.0</span>\n</td>\n<td class=\"c-ck\">\n</td>\n<td class=\"c-who dim\">T</td>\n<td class=\"c-when nowrap dim\">\n<time datetime=\"STAMP\" title=\"STAMP\">AGO</time>\n</td>\n</tr>\n</tbody>\n</table>\n</section>\n<section id=\"recent-actions\" aria-labelledby=\"r-actions\" hidden>\n<h2 id=\"r-actions\">Recent actions <a href=\"/demo/actions\">View all</a>\n</h2>\n<ul class=\"rruns\">\n</ul>\n</section>\n<section aria-labelledby=\"r-outline\">\n<h2 id=\"r-outline\">On this page</h2>\n<nav class=\"outline\" aria-label=\"Outline\">\n<a class=\"l1\" href=\"#md-demo\">Demo</a>\n<a class=\"l2\" href=\"#md-install\">Install</a>\n<a class=\"l2\" href=\"#md-usage\">Usage</a>\n</nav>\n</section>\n</aside>\n</div>\n<footer class=\"foot\">\n<span>ermite devel</span>\n<a href=\"http://example.test/ermite\" rel=\"noopener\" title=\"source of this version (AGPL-3.0-or-later)\">source</a>\n<button type=\"button\" class=\"foot-keys\" data-js data-fire=\"help\" aria-haspopup=\"dialog\" aria-controls=\"panel-help\" aria-keyshortcuts=\"?\">\n<kbd aria-hidden=\"true\">?</kbd> keyboard shortcuts</button>\n</footer>\n<div class=\"hint\" role=\"status\" aria-live=\"polite\">\n<span class=\"hint-nav\" :text=\"document.body.dataset.nav || ''\">\n</span>\n<span class=\"hint-sel\" :text=\"document.body.dataset.sel ? document.body.dataset.sel + ' · y permalink' : ''\">\n</span>\n<span class=\"hint-flash\" :text=\"document.body.dataset.flash || ''\">\n</span>\n<span class=\"hint-live\" data-state=\"connecting\" hx-sse:connect=\"/-/events?topic=repo%3Ademo&view=summary\" hx-swap=\"none\" :text=\"data.state === 'offline' ? 'live updates paused' : ''\" hx-on=\"htmx:sse:after:connection -> ermiteLive.back();\n htmx:sse:close, htmx:sse:error -> ermiteLive.lost();\n htmx:sse:error -> ermiteLive.error(event.detail.status);\n htmx:sse:before:connection -> ermiteLive.gate(event);\n home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);\n mr-head -> ermiteMR.headChanged();\n gap -> ermiteLive.reload()\">\n</span>\n</div>\n<dialog id=\"panel-help\" class=\"panel modal\" aria-label=\"Keyboard shortcuts\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<h2>Keyboard shortcuts</h2>\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd> close</button>\n</div>\n<div class=\"keys-pref\">\n<label>\n<input type=\"checkbox\" id=\"keys-off\" aria-describedby=\"keys-note\" hx-on:change=\"ermite.setKeysOff(this.checked)\"> Turn off single-key shortcuts</label>\n<p id=\"keys-note\" class=\"dim\">Single-key shortcuts are on. ctrl k and esc work whatever this says.</p>\n</div>\n<dl class=\"keys\">\n<div>\n<dt>\n<kbd>ctrl k</kbd>\n<kbd>:</kbd>\n</dt>\n<dd>go to a section, branch, tag, file or repository</dd>\n</div>\n<div>\n<dt>\n<kbd>?</kbd>\n</dt>\n<dd>this list</dd>\n</div>\n<div>\n<dt>\n<kbd>j</kbd>\n<kbd>k</kbd>\n</dt>\n<dd>move the row cursor down / up</dd>\n</div>\n<div>\n<dt>\n<kbd>enter</kbd>\n</dt>\n<dd>open the row under the cursor; on Files, a directory opens or closes in place</dd>\n</div>\n<div>\n<dt>\n<kbd>↑</kbd>\n<kbd>↓</kbd>\n<kbd>←</kbd>\n<kbd>→</kbd>\n<kbd>home</kbd>\n<kbd>end</kbd>\n</dt>\n<dd>in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file</dd>\n</div>\n<div>\n<dt>\n<kbd>l</kbd>\n<kbd>h</kbd>\n</dt>\n<dd>on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls</dd>\n</div>\n<div>\n<dt>\n<kbd>g g</kbd>\n<kbd>G</kbd>\n</dt>\n<dd>first / last row</dd>\n</div>\n<div>\n<dt>\n<kbd>/</kbd>\n</dt>\n<dd>filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)</dd>\n</div>\n<div>\n<dt>\n<kbd>b</kbd>\n</dt>\n<dd>switch branch or tag</dd>\n</div>\n<div>\n<dt>\n<kbd>s</kbd>\n<kbd>t</kbd>\n<kbd>c</kbd>\n<kbd>r</kbd>\n<kbd>m</kbd>\n<kbd>i</kbd>\n</dt>\n<dd>tabs: summary, files, commits, branches & tags, merge requests, issues</dd>\n</div>\n<div>\n<dt>\n<kbd>g h</kbd>\n</dt>\n<dd>home</dd>\n</div>\n<div>\n<dt>\n<kbd>w</kbd>\n</dt>\n<dd>wide mode: use the whole width of the screen, or not (remembered)</dd>\n</div>\n<div>\n<dt>\n<kbd>y</kbd>\n</dt>\n<dd>copy a permalink pinned to the commit</dd>\n</div>\n<div>\n<dt>\n<kbd>d</kbd>\n<kbd>u</kbd>\n<kbd>x</kbd>\n</dt>\n<dd>diff: split / unified / collapse or expand all</dd>\n</div>\n<div>\n<dt>\n<kbd>e</kbd>\n<kbd>E</kbd>\n</dt>\n<dd>diff: the whole file in view / every file, with the lines the hunks hide</dd>\n</div>\n<div>\n<dt>\n<kbd>n</kbd>\n</dt>\n<dd>merge request: next note in the diff</dd>\n</div>\n<div>\n<dt>\n<kbd>esc</kbd>\n</dt>\n<dd>close a dialog, leave a field</dd>\n</div>\n</dl>\n</dialog>\n<dialog id=\"panel-refs\" class=\"panel modal\" aria-label=\"Switch ref\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<label for=\"refs-filter\" class=\"sr\">filter branches and tags</label>\n<input id=\"refs-filter\" type=\"search\" placeholder=\"Switch branch or tag…\" autocomplete=\"off\" data-pick=\"#panel-refs li\" hx-on:input=\"ermite.filter(this)\">\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd>\n</button>\n</div>\n<div class=\"panel-cols\" data-picklist>\n<section aria-label=\"Branches\">\n<h2>Branches <span class=\"count\">2</span>\n</h2>\n<ul>\n<li>\n<a href=\"/demo/tree/feature/x\">\n<span class=\"mark\" aria-hidden=\"true\"> </span>feature/x</a>\n</li>\n<li>\n<a href=\"/demo/tree/main\" aria-current=\"true\">\n<span class=\"mark\" aria-hidden=\"true\">●</span>main</a>\n</li>\n</ul>\n</section>\n<section aria-label=\"Tags\">\n<h2>Tags <span class=\"count\">2</span>\n</h2>\n<ul>\n<li>\n<a href=\"/demo/tree/v0.1.0\">\n<span class=\"mark\" aria-hidden=\"true\"> </span>v0.1.0</a>\n</li>\n<li>\n<a href=\"/demo/tree/v0.2.0\">\n<span class=\"mark\" aria-hidden=\"true\"> </span>v0.2.0</a>\n</li>\n</ul>\n</section>\n</div>\n</dialog>\n<dialog id=\"panel-cmd\" class=\"panel modal\" aria-label=\"Go to\" hx-on:close=\"ermiteFinder.paletteClose()\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<label for=\"cmd-q\" class=\"sr\">go to</label>\n<input id=\"cmd-q\" type=\"search\" placeholder=\"Go to a section, branch, tag, file or repository…\" autocomplete=\"off\" spellcheck=\"false\" role=\"combobox\" aria-autocomplete=\"list\" aria-expanded=\"true\" aria-controls=\"cmd-list\" aria-activedescendant=\"cmd-o0\" hx-on:input=\"ermite.cmdFilter(this); ermiteFinder.palette(this)\" hx-on:keydown=\"ermite.cmdKey(event)\">\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd>\n</button>\n</div>\n<ul id=\"cmd-list\" class=\"cmd-list\" role=\"listbox\" aria-label=\"Targets\">\n<li id=\"cmd-o0\" role=\"option\" aria-selected=\"true\" data-k=\"go home\" data-cursor>\n<a href=\"/\" tabindex=\"-1\">\n<span class=\"lbl\">home</span>\n<span class=\"k\">go</span>\n</a>\n</li>\n<li id=\"cmd-o1\" role=\"option\" aria-selected=\"false\" data-k=\"section summary\">\n<a href=\"/demo\" tabindex=\"-1\">\n<span class=\"lbl\">summary</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o2\" role=\"option\" aria-selected=\"false\" data-k=\"section files\">\n<a href=\"/demo/tree/main\" tabindex=\"-1\">\n<span class=\"lbl\">files</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o3\" role=\"option\" aria-selected=\"false\" data-k=\"section commits\">\n<a href=\"/demo/commits/main\" tabindex=\"-1\">\n<span class=\"lbl\">commits</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o4\" role=\"option\" aria-selected=\"false\" data-k=\"section branches & tags\">\n<a href=\"/demo/refs\" tabindex=\"-1\">\n<span class=\"lbl\">branches & tags</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o5\" role=\"option\" aria-selected=\"false\" data-k=\"section merge requests\">\n<a href=\"/demo/merge-requests\" tabindex=\"-1\">\n<span class=\"lbl\">merge requests</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o6\" role=\"option\" aria-selected=\"false\" data-k=\"section actions\">\n<a href=\"/demo/actions\" tabindex=\"-1\">\n<span class=\"lbl\">actions</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o7\" role=\"option\" aria-selected=\"false\" data-k=\"branch feature/x\">\n<a href=\"/demo/tree/feature/x\" tabindex=\"-1\">\n<span class=\"lbl\">feature/x</span>\n<span class=\"k\">branch</span>\n</a>\n</li>\n<li id=\"cmd-o8\" role=\"option\" aria-selected=\"false\" data-k=\"branch main\">\n<a href=\"/demo/tree/main\" tabindex=\"-1\">\n<span class=\"lbl\">main</span>\n<span class=\"k\">branch</span>\n</a>\n</li>\n<li id=\"cmd-o9\" role=\"option\" aria-selected=\"false\" data-k=\"tag v0.1.0\">\n<a href=\"/demo/tree/v0.1.0\" tabindex=\"-1\">\n<span class=\"lbl\">v0.1.0</span>\n<span class=\"k\">tag</span>\n</a>\n</li>\n<li id=\"cmd-o10\" role=\"option\" aria-selected=\"false\" data-k=\"tag v0.2.0\">\n<a href=\"/demo/tree/v0.2.0\" tabindex=\"-1\">\n<span class=\"lbl\">v0.2.0</span>\n<span class=\"k\">tag</span>\n</a>\n</li>\n<li id=\"cmd-o11\" role=\"option\" aria-selected=\"false\" data-k=\"repo quiet\">\n<a href=\"/quiet\" tabindex=\"-1\">\n<span class=\"lbl\">quiet</span>\n<span class=\"k\">repo</span>\n</a>\n</li>\n<li id=\"cmd-o12\" role=\"option\" aria-selected=\"false\" data-k=\"action turn single-key shortcuts on off keyboard\">\n<a href=\"#\" data-fire=\"keys\" tabindex=\"-1\">\n<span class=\"lbl\">turn single-key shortcuts off</span>\n<span class=\"k\">action</span>\n</a>\n</li>\n</ul>\n<p class=\"panel-foot\">\n<span>\n<kbd>↑</kbd>\n<kbd>↓</kbd> move</span>\n<span>\n<kbd>enter</kbd> open</span>\n<span>\n<kbd>esc</kbd> close</span>\n</p>\n</dialog>\n<div id=\"keys\" hidden hx-on=\"k-j from:body -> ermite.move(1);\n k-k from:body -> ermite.move(-1);\n k-top from:body -> ermite.edge(false);\n k-bottom from:body -> ermite.edge(true);\n k-open from:body -> ermite.open();\n k-right from:body -> ermite.rail(true);\n k-left from:body -> ermite.rail(false);\n k-esc from:body -> ermite.closeDialogs();\n k-help from:body -> ermite.dialog('panel-help');\n k-refs from:body -> ermite.dialog('panel-refs', 'refs-filter');\n k-cmd from:body -> ermite.dialog('panel-cmd', 'cmd-q'); ermiteFinder.load();\n k-filter from:body -> ermite.focusFilter();\n k-gh from:body -> ermite.go('.brand');\n k-s from:body -> ermite.tab('s');\n k-t from:body -> ermite.tab('t');\n k-c from:body -> ermite.tab('c');\n k-r from:body -> ermite.tab('r');\n k-m from:body -> ermite.tab('m');\n k-i from:body -> ermite.tab('i');\n k-next from:body -> ermite.nextNote();\n k-split from:body -> ermite.layout('split');\n k-unified from:body -> ermite.layout('unified');\n k-collapse from:body -> ermite.collapse();\n k-wide from:body -> window.ermiteWide.toggle();\n k-expand from:body -> ermite.expandFile();\n k-expandAll from:body -> ermite.expandAll();\n k-permalink from:body -> ermite.permalink();\n k-merge from:body -> window.ermiteMR?.openMerge();\n k-read from:body -> window.ermiteMR?.markRead();\n k-gf from:body -> window.ermiteMR?.focusFiles();\n k-keys from:body -> ermite.toggleKeys()\">\n</div>\n</body>\n</html>\n"
- actual : "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<meta name=\"color-scheme\" content=\"light dark\">\n<title>demo · example.test</title>\n<meta name=\"theme-color\" media=\"(prefers-color-scheme: light)\" content=\"#ffffff\">\n<meta name=\"theme-color\" media=\"(prefers-color-scheme: dark)\" content=\"#0c0c0c\">\n<meta name=\"apple-mobile-web-app-title\" content=\"ermite\">\n<link rel=\"icon\" type=\"image/svg+xml\" href=\"/-/static/img/icon.HASH.svg\">\n<link rel=\"apple-touch-icon\" href=\"/-/static/app/apple-touch-icon.HASH.png\">\n<link rel=\"manifest\" href=\"/-/static/app/manifest.HASH.webmanifest\">\n<link rel=\"preload\" href=\"/-/static/fonts/atkinson-next.HASH.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<link rel=\"stylesheet\" href=\"/-/static/css/ermite.HASH.css\">\n<meta name=\"htmx-config\" content='{\"history\":false,\"includeIndicatorCSS\":false,\"extensions\":\"sse, hx-live\"}'>\n<script src=\"/-/static/js/htmx.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/hx-live.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/hx-sse.min.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/store.HASH.js\">\n</script>\n<script src=\"/-/static/js/ermite.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/files.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/passkey.HASH.js\" defer>\n</script>\n<script src=\"/-/static/js/log.HASH.js\" defer>\n</script>\n</head>\n<body data-ref=\"main\" data-sha=\"SHA40\" data-sel=\"\" data-nav=\"\" data-paths=\"/demo/paths/SHA40\" data-blob=\"/demo/blob/main\">\n<a class=\"skip\" href=\"#main\">skip to content</a>\n<header class=\"hdr\">\n<div class=\"hdr-top\">\n<a class=\"brand\" href=\"/\" data-g=\"h\" aria-label=\"home\" title=\"home (g h)\">\n<span class=\"brand-mark\" aria-hidden=\"true\">\n</span>\n</a>\n<nav class=\"crumbs\" aria-label=\"Path\">\n<ol>\n<li>\n<a href=\"/demo\" aria-current=\"page\">demo</a>\n</li>\n</ol>\n</nav>\n<div class=\"hdr-acts\">\n<a class=\"btn ref\" href=\"/demo/refs\" data-fire=\"refs\" aria-keyshortcuts=\"b\" title=\"switch branch or tag (b)\">\n<span class=\"ico i-branch\" aria-hidden=\"true\">\n</span>\n<span class=\"ref-name\">main</span>\n<span class=\"sha\">SHA7</span>\n</a>\n<button type=\"button\" class=\"btn search\" data-js aria-haspopup=\"dialog\" aria-controls=\"panel-cmd\" aria-keyshortcuts=\"Control+K :\" title=\"go to a section, ref, file or repo (ctrl k or :)\" data-fire=\"cmd\">\n<span class=\"ico i-search\" aria-hidden=\"true\">\n</span>\n<span class=\"search-label\">Go to…</span>\n<kbd aria-hidden=\"true\">ctrl k</kbd>\n</button>\n</div>\n</div>\n<nav class=\"tabs\" aria-label=\"Sections\">\n<ul>\n<li>\n<a href=\"/demo\" data-key=\"s\" aria-keyshortcuts=\"s\" aria-current=\"page\">Summary <kbd aria-hidden=\"true\">s</kbd>\n</a>\n</li>\n<li>\n<a href=\"/demo/tree/main\" data-key=\"t\" aria-keyshortcuts=\"t\">Files <kbd aria-hidden=\"true\">t</kbd>\n</a>\n</li>\n<li>\n<a href=\"/demo/commits/main\" data-key=\"c\" aria-keyshortcuts=\"c\">Commits <kbd aria-hidden=\"true\">c</kbd>\n</a>\n</li>\n<li>\n<a href=\"/demo/refs\" data-key=\"r\" aria-keyshortcuts=\"r\">Branches & tags <kbd aria-hidden=\"true\">r</kbd>\n</a>\n</li>\n<li>\n<a href=\"/demo/merge-requests\" data-key=\"m\" aria-keyshortcuts=\"m\">Merge requests <kbd aria-hidden=\"true\">m</kbd>\n</a>\n</li>\n<li>\n<a href=\"/demo/actions\" data-key=\"a\" aria-keyshortcuts=\"a\">Actions <kbd aria-hidden=\"true\">a</kbd>\n</a>\n</li>\n</ul>\n</nav>\n</header>\n<div class=\"work has-rail\">\n<section class=\"work-lede\" aria-label=\"Description\">\n<p class=\"lede\">A demo repository</p>\n</section>\n<main id=\"main\" tabindex=\"-1\">\n<section class=\"card readme\" aria-labelledby=\"readme-h\">\n<h2 class=\"card-h\" id=\"readme-h\">\n<span class=\"ico i-file\" aria-hidden=\"true\">\n</span> README.md</h2>\n<article class=\"prose\" aria-label=\"README.md\" hx-ignore>\n<h1 id=\"md-demo\">Demo</h1>\n<p>A small <em>demo</em> with a <a href=\"/demo/blob/main/docs/guide.md\">guide</a> and <a href=\"https://example.org/x\" rel=\"nofollow noopener noreferrer\">the site</a>.</p>\n<h2 id=\"md-install\">Install</h2>\n<pre class=\"chroma\">\n<code class=\"language-sh\">go install example.org/demo@latest\n</code>\n</pre>\n<h2 id=\"md-usage\">Usage</h2>\n<table>\n<thead>\n<tr>\n<th>a</th>\n<th align=\"right\">b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td align=\"right\">2</td>\n</tr>\n</tbody>\n</table>\n</article>\n</section>\n</main>\n<aside class=\"rail\" aria-label=\"Context\">\n<section aria-labelledby=\"r-clone\">\n<h2 id=\"r-clone\">Clone</h2>\n<div class=\"clone\" id=\"clone-demo\">\n<div class=\"clone-line\">\n<span class=\"mute\" aria-hidden=\"true\">$ </span>\n<code>git clone http://example.test/demo.git</code>\n<button type=\"button\" class=\"btn copy\" data-js data-label=\"Copy\" aria-label=\"copy: git clone http://example.test/demo.git\" hx-on:click=\"ermite.copy(this)\">Copy</button>\n</div>\n</div>\n</section>\n<section aria-labelledby=\"r-facts\">\n<h2 id=\"r-facts\">About</h2>\n<dl class=\"kv\">\n<dt>last push</dt>\n<dd id=\"last-push-demo\">\n<time datetime=\"STAMP\">AGO · STAMP</time>\n</dd>\n<dt>branch</dt>\n<dd>main · 2 branches</dd>\n<dt>created</dt>\n<dd>\n<time datetime=\"STAMP\">STAMP</time>\n</dd>\n<dt>latest tag</dt>\n<dd class=\"latest-tag\">\n<a class=\"tag-name\" href=\"/demo/tree/v0.2.0\" title=\"add main.go\">v0.2.0</a> · <time datetime=\"STAMP\" title=\"STAMP\">AGO</time> · <a class=\"all-tags\" href=\"/demo/refs\">2 tags</a>\n</dd>\n</dl>\n</section>\n<section aria-labelledby=\"r-recent\">\n<h2 id=\"r-recent\">Recent commits <a href=\"/demo/commits/main\">View all</a>\n</h2>\n<table class=\"list commits\" aria-label=\"Commits\">\n<tbody data-rows>\n<tr data-cursor>\n<td class=\"c-sha mute\">SHA7</td>\n<td class=\"c-subject\">\n<a href=\"/demo/commit/SHA40\">add main.go</a>\n<span class=\"pill\">main</span>\n<span class=\"pill tag\">\n<span class=\"sr\">tag </span>v0.2.0</span>\n</td>\n<td class=\"c-ck\">\n</td>\n<td class=\"c-who dim\">T</td>\n<td class=\"c-when nowrap dim\">\n<time datetime=\"STAMP\" title=\"STAMP\">AGO</time>\n</td>\n</tr>\n<tr>\n<td class=\"c-sha mute\">SHA7</td>\n<td class=\"c-subject\">\n<a href=\"/demo/commit/SHA40\">first commit</a>\n<span class=\"pill tag\">\n<span class=\"sr\">tag </span>v0.1.0</span>\n</td>\n<td class=\"c-ck\">\n</td>\n<td class=\"c-who dim\">T</td>\n<td class=\"c-when nowrap dim\">\n<time datetime=\"STAMP\" title=\"STAMP\">AGO</time>\n</td>\n</tr>\n</tbody>\n</table>\n</section>\n<section id=\"recent-actions\" aria-labelledby=\"r-actions\" hidden>\n<h2 id=\"r-actions\">Recent actions <a href=\"/demo/actions\">View all</a>\n</h2>\n<ul class=\"rruns\">\n</ul>\n</section>\n<section aria-labelledby=\"r-outline\">\n<h2 id=\"r-outline\">On this page</h2>\n<nav class=\"outline\" aria-label=\"Outline\">\n<a class=\"l1\" href=\"#md-demo\">Demo</a>\n<a class=\"l2\" href=\"#md-install\">Install</a>\n<a class=\"l2\" href=\"#md-usage\">Usage</a>\n</nav>\n</section>\n</aside>\n</div>\n<footer class=\"foot\">\n<span>ermite devel</span>\n<a href=\"http://example.test/ermite\" rel=\"noopener\" title=\"source of this version (AGPL-3.0-or-later)\">source</a>\n<button type=\"button\" class=\"foot-keys\" data-js data-fire=\"help\" aria-haspopup=\"dialog\" aria-controls=\"panel-help\" aria-keyshortcuts=\"?\">\n<kbd aria-hidden=\"true\">?</kbd> keyboard shortcuts</button>\n</footer>\n<div class=\"hint\" role=\"status\" aria-live=\"polite\">\n<span class=\"hint-nav\" :text=\"document.body.dataset.nav || ''\">\n</span>\n<span class=\"hint-sel\" :text=\"document.body.dataset.sel ? document.body.dataset.sel + ' · y permalink' : ''\">\n</span>\n<span class=\"hint-flash\" :text=\"document.body.dataset.flash || ''\">\n</span>\n<span class=\"hint-live\" data-state=\"connecting\" hx-sse:connect=\"/-/events?topic=repo%3Ademo&view=summary\" hx-swap=\"none\" :text=\"data.state === 'offline' ? 'live updates paused' : ''\" hx-on=\"htmx:sse:after:connection -> ermiteLive.back();\n htmx:sse:close, htmx:sse:error -> ermiteLive.lost();\n htmx:sse:error -> ermiteLive.error(event.detail.status);\n htmx:sse:before:connection -> ermiteLive.gate(event);\n home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);\n mr-head -> ermiteMR.headChanged();\n gap -> ermiteLive.reload()\">\n</span>\n</div>\n<dialog id=\"panel-help\" class=\"panel modal\" aria-label=\"Keyboard shortcuts\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<h2>Keyboard shortcuts</h2>\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd> close</button>\n</div>\n<div class=\"keys-pref\">\n<label>\n<input type=\"checkbox\" id=\"keys-off\" aria-describedby=\"keys-note\" hx-on:change=\"ermite.setKeysOff(this.checked)\"> Turn off single-key shortcuts</label>\n<p id=\"keys-note\" class=\"dim\">Single-key shortcuts are on. ctrl k and esc work whatever this says.</p>\n</div>\n<dl class=\"keys\">\n<div>\n<dt>\n<kbd>ctrl k</kbd>\n<kbd>:</kbd>\n</dt>\n<dd>go to a section, branch, tag, file or repository</dd>\n</div>\n<div>\n<dt>\n<kbd>?</kbd>\n</dt>\n<dd>this list</dd>\n</div>\n<div>\n<dt>\n<kbd>j</kbd>\n<kbd>k</kbd>\n</dt>\n<dd>move the row cursor down / up</dd>\n</div>\n<div>\n<dt>\n<kbd>enter</kbd>\n</dt>\n<dd>open the row under the cursor; on Files, a directory opens or closes in place</dd>\n</div>\n<div>\n<dt>\n<kbd>↑</kbd>\n<kbd>↓</kbd>\n<kbd>←</kbd>\n<kbd>→</kbd>\n<kbd>home</kbd>\n<kbd>end</kbd>\n</dt>\n<dd>in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file</dd>\n</div>\n<div>\n<dt>\n<kbd>l</kbd>\n<kbd>h</kbd>\n</dt>\n<dd>on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls</dd>\n</div>\n<div>\n<dt>\n<kbd>g g</kbd>\n<kbd>G</kbd>\n</dt>\n<dd>first / last row</dd>\n</div>\n<div>\n<dt>\n<kbd>/</kbd>\n</dt>\n<dd>filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)</dd>\n</div>\n<div>\n<dt>\n<kbd>b</kbd>\n</dt>\n<dd>switch branch or tag</dd>\n</div>\n<div>\n<dt>\n<kbd>s</kbd>\n<kbd>t</kbd>\n<kbd>c</kbd>\n<kbd>r</kbd>\n<kbd>m</kbd>\n<kbd>i</kbd>\n</dt>\n<dd>tabs: summary, files, commits, branches & tags, merge requests, issues</dd>\n</div>\n<div>\n<dt>\n<kbd>g h</kbd>\n</dt>\n<dd>home</dd>\n</div>\n<div>\n<dt>\n<kbd>w</kbd>\n</dt>\n<dd>wide mode: use the whole width of the screen, or not (remembered)</dd>\n</div>\n<div>\n<dt>\n<kbd>y</kbd>\n</dt>\n<dd>copy a permalink pinned to the commit</dd>\n</div>\n<div>\n<dt>\n<kbd>d</kbd>\n<kbd>u</kbd>\n<kbd>x</kbd>\n</dt>\n<dd>diff: split / unified / collapse or expand all</dd>\n</div>\n<div>\n<dt>\n<kbd>e</kbd>\n<kbd>E</kbd>\n</dt>\n<dd>diff: the whole file in view / every file, with the lines the hunks hide</dd>\n</div>\n<div>\n<dt>\n<kbd>n</kbd>\n</dt>\n<dd>merge request: next note in the diff</dd>\n</div>\n<div>\n<dt>\n<kbd>esc</kbd>\n</dt>\n<dd>close a dialog, leave a field</dd>\n</div>\n</dl>\n</dialog>\n<dialog id=\"panel-refs\" class=\"panel modal\" aria-label=\"Switch ref\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<label for=\"refs-filter\" class=\"sr\">filter branches and tags</label>\n<input id=\"refs-filter\" type=\"search\" placeholder=\"Switch branch or tag…\" autocomplete=\"off\" data-pick=\"#panel-refs li\" hx-on:input=\"ermite.filter(this)\">\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd>\n</button>\n</div>\n<div class=\"panel-cols\" data-picklist>\n<section aria-label=\"Branches\">\n<h2>Branches <span class=\"count\">2</span>\n</h2>\n<ul>\n<li>\n<a href=\"/demo/tree/feature/x\">\n<span class=\"mark\" aria-hidden=\"true\"> </span>feature/x</a>\n</li>\n<li>\n<a href=\"/demo/tree/main\" aria-current=\"true\">\n<span class=\"mark\" aria-hidden=\"true\">●</span>main</a>\n</li>\n</ul>\n</section>\n<section aria-label=\"Tags\">\n<h2>Tags <span class=\"count\">2</span>\n</h2>\n<ul>\n<li>\n<a href=\"/demo/tree/v0.1.0\">\n<span class=\"mark\" aria-hidden=\"true\"> </span>v0.1.0</a>\n</li>\n<li>\n<a href=\"/demo/tree/v0.2.0\">\n<span class=\"mark\" aria-hidden=\"true\"> </span>v0.2.0</a>\n</li>\n</ul>\n</section>\n</div>\n</dialog>\n<dialog id=\"panel-cmd\" class=\"panel modal\" aria-label=\"Go to\" hx-on:close=\"ermiteFinder.paletteClose()\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\">\n<div class=\"panel-head\">\n<label for=\"cmd-q\" class=\"sr\">go to</label>\n<input id=\"cmd-q\" type=\"search\" placeholder=\"Go to a section, branch, tag, file or repository…\" autocomplete=\"off\" spellcheck=\"false\" role=\"combobox\" aria-autocomplete=\"list\" aria-expanded=\"true\" aria-controls=\"cmd-list\" aria-activedescendant=\"cmd-o0\" hx-on:input=\"ermite.cmdFilter(this); ermiteFinder.palette(this)\" hx-on:keydown=\"ermite.cmdKey(event)\">\n<button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\">\n<kbd>esc</kbd>\n</button>\n</div>\n<ul id=\"cmd-list\" class=\"cmd-list\" role=\"listbox\" aria-label=\"Targets\">\n<li id=\"cmd-o0\" role=\"option\" aria-selected=\"true\" data-k=\"go home\" data-cursor>\n<a href=\"/\" tabindex=\"-1\">\n<span class=\"lbl\">home</span>\n<span class=\"k\">go</span>\n</a>\n</li>\n<li id=\"cmd-o1\" role=\"option\" aria-selected=\"false\" data-k=\"section summary\">\n<a href=\"/demo\" tabindex=\"-1\">\n<span class=\"lbl\">summary</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o2\" role=\"option\" aria-selected=\"false\" data-k=\"section files\">\n<a href=\"/demo/tree/main\" tabindex=\"-1\">\n<span class=\"lbl\">files</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o3\" role=\"option\" aria-selected=\"false\" data-k=\"section commits\">\n<a href=\"/demo/commits/main\" tabindex=\"-1\">\n<span class=\"lbl\">commits</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o4\" role=\"option\" aria-selected=\"false\" data-k=\"section branches & tags\">\n<a href=\"/demo/refs\" tabindex=\"-1\">\n<span class=\"lbl\">branches & tags</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o5\" role=\"option\" aria-selected=\"false\" data-k=\"section merge requests\">\n<a href=\"/demo/merge-requests\" tabindex=\"-1\">\n<span class=\"lbl\">merge requests</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o6\" role=\"option\" aria-selected=\"false\" data-k=\"section actions\">\n<a href=\"/demo/actions\" tabindex=\"-1\">\n<span class=\"lbl\">actions</span>\n<span class=\"k\">section</span>\n</a>\n</li>\n<li id=\"cmd-o7\" role=\"option\" aria-selected=\"false\" data-k=\"branch feature/x\">\n<a href=\"/demo/tree/feature/x\" tabindex=\"-1\">\n<span class=\"lbl\">feature/x</span>\n<span class=\"k\">branch</span>\n</a>\n</li>\n<li id=\"cmd-o8\" role=\"option\" aria-selected=\"false\" data-k=\"branch main\">\n<a href=\"/demo/tree/main\" tabindex=\"-1\">\n<span class=\"lbl\">main</span>\n<span class=\"k\">branch</span>\n</a>\n</li>\n<li id=\"cmd-o9\" role=\"option\" aria-selected=\"false\" data-k=\"tag v0.1.0\">\n<a href=\"/demo/tree/v0.1.0\" tabindex=\"-1\">\n<span class=\"lbl\">v0.1.0</span>\n<span class=\"k\">tag</span>\n</a>\n</li>\n<li id=\"cmd-o10\" role=\"option\" aria-selected=\"false\" data-k=\"tag v0.2.0\">\n<a href=\"/demo/tree/v0.2.0\" tabindex=\"-1\">\n<span class=\"lbl\">v0.2.0</span>\n<span class=\"k\">tag</span>\n</a>\n</li>\n<li id=\"cmd-o11\" role=\"option\" aria-selected=\"false\" data-k=\"repo quiet\">\n<a href=\"/quiet\" tabindex=\"-1\">\n<span class=\"lbl\">quiet</span>\n<span class=\"k\">repo</span>\n</a>\n</li>\n<li id=\"cmd-o12\" role=\"option\" aria-selected=\"false\" data-k=\"action turn single-key shortcuts on off keyboard\">\n<a href=\"#\" data-fire=\"keys\" tabindex=\"-1\">\n<span class=\"lbl\">turn single-key shortcuts off</span>\n<span class=\"k\">action</span>\n</a>\n</li>\n</ul>\n<p class=\"panel-foot\">\n<span>\n<kbd>↑</kbd>\n<kbd>↓</kbd> move</span>\n<span>\n<kbd>enter</kbd> open</span>\n<span>\n<kbd>esc</kbd> close</span>\n</p>\n</dialog>\n<div id=\"keys\" hidden hx-on=\"k-j from:body -> ermite.move(1);\n k-k from:body -> ermite.move(-1);\n k-top from:body -> ermite.edge(false);\n k-bottom from:body -> ermite.edge(true);\n k-open from:body -> ermite.open();\n k-right from:body -> ermite.rail(true);\n k-left from:body -> ermite.rail(false);\n k-esc from:body -> ermite.closeDialogs();\n k-help from:body -> ermite.dialog('panel-help');\n k-refs from:body -> ermite.dialog('panel-refs', 'refs-filter');\n k-cmd from:body -> ermite.dialog('panel-cmd', 'cmd-q'); ermiteFinder.load();\n k-filter from:body -> ermite.focusFilter();\n k-gh from:body -> ermite.go('.brand');\n k-s from:body -> ermite.tab('s');\n k-t from:body -> ermite.tab('t');\n k-c from:body -> ermite.tab('c');\n k-r from:body -> ermite.tab('r');\n k-m from:body -> ermite.tab('m');\n k-i from:body -> ermite.tab('i');\n k-next from:body -> ermite.nextNote();\n k-split from:body -> ermite.layout('split');\n k-unified from:body -> ermite.layout('unified');\n k-collapse from:body -> ermite.collapse();\n k-wide from:body -> window.ermiteWide.toggle();\n k-expand from:body -> ermite.expandFile();\n k-expandAll from:body -> ermite.expandAll();\n k-permalink from:body -> ermite.permalink();\n k-merge from:body -> window.ermiteMR?.openMerge();\n k-read from:body -> window.ermiteMR?.markRead();\n k-gf from:body -> window.ermiteMR?.focusFiles();\n k-keys from:body -> ermite.toggleKeys()\">\n</div>\n</body>\n</html>\n"
- Diff:
- --- Expected
- +++ Actual
- @@ -105,3 +105,3 @@
- <h2 id="md-install">Install</h2>
- -<pre>
- +<pre class="chroma">
- <code class="language-sh">go install example.org/demo@latest
- Test: TestWebGolden/summary
- Messages: summary
- FAIL
- FAIL bnema.dev/ermite/internal/app 397.953s
- FAIL
- Process completed with exit code 1.
- Post job cleanup.
- ##[command]/usr/bin/docker exec ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67 sh -c "cat /etc/*release | grep ^ID"
- [command]/usr/sbin/git version
- git version 2.56.0
- Copying '/github/home/.gitconfig' to '/__w/_temp/24abc5ab-caea-42d9-b493-25fc2a324edf/.gitconfig'
- Temporarily overriding HOME='/__w/_temp/24abc5ab-caea-42d9-b493-25fc2a324edf' before making global git config changes
- Adding repository directory to the temporary git global config as a safe directory
- [command]/usr/sbin/git config --global --add safe.directory /__w/ermite/ermite
- Removing SSH command configuration
- [command]/usr/sbin/git config --local --name-only --get-regexp core\.sshCommand
- [command]/usr/sbin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
- Removing HTTP extra header
- [command]/usr/sbin/git config --local --name-only --get-regexp http\.http\:\/\/ermite\:7341\/\.extraheader
- [command]/usr/sbin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.http\:\/\/ermite\:7341\/\.extraheader' && git config --local --unset-all 'http.http://ermite:7341/.extraheader' || :"
- Removing includeIf entries pointing to credentials config files
- [command]/usr/sbin/git config --local --name-only --get-regexp ^includeIf\.gitdir:
- includeif.gitdir:/__w/ermite/ermite/.git.path
- includeif.gitdir:/__w/ermite/ermite/.git/worktrees/*.path
- includeif.gitdir:/github/workspace/.git.path
- includeif.gitdir:/github/workspace/.git/worktrees/*.path
- [command]/usr/sbin/git config --local --get-all includeif.gitdir:/__w/ermite/ermite/.git.path
- /__w/_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git config --local --unset includeif.gitdir:/__w/ermite/ermite/.git.path /__w/_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git config --local --get-all includeif.gitdir:/__w/ermite/ermite/.git/worktrees/*.path
- /__w/_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git config --local --unset includeif.gitdir:/__w/ermite/ermite/.git/worktrees/*.path /__w/_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git config --local --get-all includeif.gitdir:/github/workspace/.git.path
- /github/runner_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git config --local --unset includeif.gitdir:/github/workspace/.git.path /github/runner_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git config --local --get-all includeif.gitdir:/github/workspace/.git/worktrees/*.path
- /github/runner_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git config --local --unset includeif.gitdir:/github/workspace/.git/worktrees/*.path /github/runner_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config
- [command]/usr/sbin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url
- Removing credentials config '/__w/_temp/git-credentials-7cf399f0-81f6-410c-a48a-32ca42282e5d.config'
- Stop and remove container: 41d7e15d96cb476cacaaf7eba549d051_archlinuxlatest_dabbed
- ##[command]/usr/bin/docker rm --force ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67
- ddeb508ec991c698a2592c005268363fe5fe06647e528108dd30975998168e67
- Remove container network: github_network_40ce9edffbdd4c32a84ae386508ecceb
- ##[command]/usr/bin/docker network rm github_network_40ce9edffbdd4c32a84ae386508ecceb
- github_network_40ce9edffbdd4c32a84ae386508ecceb
- Cleaning up orphan processes
- ##[warning]Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/setup-go@v5. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/