Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
name: build + test + amalgamate (nix)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
Expand All @@ -39,7 +39,7 @@ jobs:
name: vt_gif renderer checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
Expand All @@ -49,7 +49,7 @@ jobs:
name: static website + downloadable header
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
Expand All @@ -70,7 +70,7 @@ jobs:
name: libvterm round-trip (Tier A)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
Expand All @@ -87,7 +87,7 @@ jobs:
matrix:
san: [address, undefined, thread]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
Expand Down
288 changes: 278 additions & 10 deletions .github/workflows/hosted-visual-probe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,87 @@ jobs:
runs-on: macos-15
timeout-minutes: 35
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v27
id: install-nix
continue-on-error: true
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: actions/checkout@v7
- name: Run hosted iTerm2 probe
env:
TIMUI_HOSTED_NIX_STATUS: ${{ steps.install-nix.outcome }}
TIMUI_HOSTED_NIX_STATUS: skipped
run: bash tools/ci/hosted_visual_macos.sh "${{ inputs.frames }}"
- name: Upload macOS visual evidence
id: upload-macos-evidence
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: hosted-visual-macos-iterm2
path: artifacts/hosted-visual/macos
if-no-files-found: error
retention-days: 14
- name: Upload iTerm2 window screenshot
id: upload-macos-iterm2-window
if: always()
uses: actions/upload-artifact@v7
with:
name: iterm2-window.png
path: artifacts/hosted-visual/macos/iterm2-window-12s.png
if-no-files-found: ignore
retention-days: 14
archive: false
- name: Summarize macOS visual evidence
if: always()
env:
EVIDENCE_URL: ${{ steps.upload-macos-evidence.outputs.artifact-url }}
ITERM2_WINDOW_URL: ${{ steps.upload-macos-iterm2-window.outputs.artifact-url }}
run: |
evidence="artifacts/hosted-visual/macos/evidence.md"

add_row() {
name="$1"
path="$2"
url="$3"
status="missing"
if [ -f "${path}" ]; then
status="captured"
fi
link="not uploaded"
if [ -n "${url}" ]; then
link="[open artifact](${url})"
fi
printf "| \`%s\` | %s | %s |\n" "${name}" "${status}" "${link}" >> "${GITHUB_STEP_SUMMARY}"
}

{
echo "## macOS iTerm2 Visual Evidence"
echo
if [ -n "${EVIDENCE_URL}" ]; then
echo "- Full evidence bundle: [hosted-visual-macos-iterm2](${EVIDENCE_URL})"
else
echo "- Full evidence bundle: not uploaded"
fi
echo
echo "| Screenshot | Status | Link |"
echo "| --- | --- | --- |"
} >> "${GITHUB_STEP_SUMMARY}"

add_row "iTerm2 window" "artifacts/hosted-visual/macos/iterm2-window-12s.png" "${ITERM2_WINDOW_URL}"

{
echo
echo "> Inline thumbnails are published by the Visual screenshot summary job after both platform probes finish."
if [ -f "${evidence}" ]; then
echo
echo "<details><summary>Evidence notes</summary>"
echo
sed -n '1,220p' "${evidence}"
echo
echo "</details>"
fi
} >> "${GITHUB_STEP_SUMMARY}"

windows-terminal:
name: Windows Terminal screenshot + ConPTY probe
runs-on: windows-latest
timeout-minutes: 35
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- uses: msys2/setup-msys2@v2
id: setup-msys2
with:
Expand All @@ -69,10 +125,222 @@ jobs:
TIMUI_MSYS2_LOCATION: ${{ steps.setup-msys2.outputs.msys2-location }}
run: ./tools/ci/hosted_visual_windows.ps1 -Frames "${{ inputs.frames }}"
- name: Upload Windows visual evidence
id: upload-windows-evidence
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: hosted-visual-windows-terminal
path: artifacts/hosted-visual/windows
if-no-files-found: error
retention-days: 14
- name: Upload Windows direct Sixel screenshot
id: upload-windows-direct-sixel
if: always()
uses: actions/upload-artifact@v7
with:
name: windows-terminal-direct-sixel.png
path: artifacts/hosted-visual/windows/windows-terminal-direct-sixel-12s.png
if-no-files-found: ignore
retention-days: 14
archive: false
- name: Upload Windows Terminal Sixel screenshot
id: upload-windows-sixel-12s
if: always()
uses: actions/upload-artifact@v7
with:
name: windows-terminal-sixel.png
path: artifacts/hosted-visual/windows/windows-terminal-sixel-12s.png
if-no-files-found: ignore
retention-days: 14
archive: false
- name: Summarize Windows visual evidence
if: always()
shell: pwsh
env:
EVIDENCE_URL: ${{ steps.upload-windows-evidence.outputs.artifact-url }}
DIRECT_SIXEL_URL: ${{ steps.upload-windows-direct-sixel.outputs.artifact-url }}
SIXEL_12S_URL: ${{ steps.upload-windows-sixel-12s.outputs.artifact-url }}
run: |
$summary = $env:GITHUB_STEP_SUMMARY
$evidence = "artifacts/hosted-visual/windows/evidence.md"
$rows = @(
@{ Name = "Windows direct Sixel"; Path = "artifacts/hosted-visual/windows/windows-terminal-direct-sixel-12s.png"; Url = $env:DIRECT_SIXEL_URL },
@{ Name = "Windows Terminal Sixel"; Path = "artifacts/hosted-visual/windows/windows-terminal-sixel-12s.png"; Url = $env:SIXEL_12S_URL }
)

Add-Content -Path $summary -Value "## Windows Terminal Visual Evidence"
Add-Content -Path $summary -Value ""
if ($env:EVIDENCE_URL) {
Add-Content -Path $summary -Value "- Full evidence bundle: [hosted-visual-windows-terminal]($env:EVIDENCE_URL)"
} else {
Add-Content -Path $summary -Value "- Full evidence bundle: not uploaded"
}
Add-Content -Path $summary -Value ""
Add-Content -Path $summary -Value "| Screenshot | Status | Link |"
Add-Content -Path $summary -Value "| --- | --- | --- |"
foreach ($row in $rows) {
$status = if (Test-Path $row.Path) { "captured" } else { "missing" }
$link = if ($row.Url) { "[open artifact]($($row.Url))" } else { "not uploaded" }
Add-Content -Path $summary -Value "| ``$($row.Name)`` | $status | $link |"
}
Add-Content -Path $summary -Value ""
Add-Content -Path $summary -Value "> Inline thumbnails are published by the Visual screenshot summary job after both platform probes finish."
if (Test-Path $evidence) {
Add-Content -Path $summary -Value ""
Add-Content -Path $summary -Value "<details><summary>Evidence notes</summary>"
Add-Content -Path $summary -Value ""
Get-Content -Path $evidence -TotalCount 220 | Add-Content -Path $summary
Add-Content -Path $summary -Value ""
Add-Content -Path $summary -Value "</details>"
}

visual-summary:
name: Visual screenshot summary
runs-on: ubuntu-latest
needs:
- macos-iterm2
- windows-terminal
if: always()
permissions:
actions: read
contents: write
steps:
- name: Download hosted visual evidence
id: download-visual-evidence
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
mkdir -p visual-artifacts
gh run download "${GITHUB_RUN_ID}" \
--repo "${GH_REPO}" \
--pattern "hosted-visual-*" \
--dir visual-artifacts
- name: Publish inline screenshot gallery
env:
GH_REPO: ${{ github.repository }}
GITHUB_TOKEN: ${{ github.token }}
SCREENSHOT_BRANCH: ci-screenshots
RUN_PATH: runs/${{ github.run_id }}/${{ github.run_attempt }}
shell: bash
run: |
set -euo pipefail

src_root="${GITHUB_WORKSPACE}/visual-artifacts"
publish_root="${RUNNER_TEMP}/timui-screenshots-publish-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
remote_url="https://x-access-token:${GITHUB_TOKEN}@github.com/${GH_REPO}.git"
raw_base_url="https://github.com/${GH_REPO}/raw/${SCREENSHOT_BRANCH}/${RUN_PATH}"
blob_base_url="https://github.com/${GH_REPO}/blob/${SCREENSHOT_BRANCH}/${RUN_PATH}"
run_url="https://github.com/${GH_REPO}/actions/runs/${GITHUB_RUN_ID}"
branch_run_url="https://github.com/${GH_REPO}/tree/${SCREENSHOT_BRANCH}/${RUN_PATH}"

if git ls-remote --exit-code --heads "${remote_url}" "${SCREENSHOT_BRANCH}" >/dev/null 2>&1; then
git clone --depth=1 --branch "${SCREENSHOT_BRANCH}" "${remote_url}" "${publish_root}"
else
mkdir -p "${publish_root}"
git init -b "${SCREENSHOT_BRANCH}" "${publish_root}"
git -C "${publish_root}" remote add origin "${remote_url}"
fi

cd "${publish_root}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

mkdir -p "${RUN_PATH}/macos" "${RUN_PATH}/windows"

copy_named() {
local platform="$1"
local artifact="$2"
local name="$3"
local dest="${4:-${name}}"
local artifact_dir="${src_root}/${artifact}"
local match=""

if [ -d "${artifact_dir}" ]; then
match="$(find "${artifact_dir}" -type f -name "${name}" -print -quit)"
fi

if [ -n "${match}" ]; then
cp "${match}" "${RUN_PATH}/${platform}/${dest}"
fi
}

copy_named macos hosted-visual-macos-iterm2 iterm2-window-12s.png iterm2-window.png
copy_named macos hosted-visual-macos-iterm2 evidence.md

copy_named windows hosted-visual-windows-terminal windows-terminal-direct-sixel-12s.png windows-terminal-direct-sixel.png
copy_named windows hosted-visual-windows-terminal windows-terminal-sixel-12s.png windows-terminal-sixel.png
copy_named windows hosted-visual-windows-terminal evidence.md

cat > "${RUN_PATH}/README.md" <<EOF
# timui.h hosted visual evidence

- Workflow run: ${run_url}
- Attempt: ${GITHUB_RUN_ATTEMPT}
- Source ref: ${GITHUB_REF_NAME}
- Source SHA: ${GITHUB_SHA}
EOF

git add "${RUN_PATH}"
if ! git diff --cached --quiet; then
git commit -m "visual: publish run ${GITHUB_RUN_ID}.${GITHUB_RUN_ATTEMPT}"

pushed=0
for attempt in 1 2 3; do
if git push origin "HEAD:${SCREENSHOT_BRANCH}"; then
pushed=1
break
fi

if [ "${attempt}" -eq 3 ]; then
break
fi

git fetch --depth=1 origin "${SCREENSHOT_BRANCH}"
git rebase "origin/${SCREENSHOT_BRANCH}"
done

if [ "${pushed}" -ne 1 ]; then
echo "failed to publish screenshots to ${SCREENSHOT_BRANCH}" >&2
exit 1
fi
fi

add_image() {
local title="$1"
local platform="$2"
local name="$3"
local file="${RUN_PATH}/${platform}/${name}"
local raw_url="${raw_base_url}/${platform}/${name}"
local blob_url="${blob_base_url}/${platform}/${name}"

{
echo "### ${title}"
echo
if [ -f "${file}" ]; then
echo "[open file](${blob_url})"
echo
echo "<img width=\"900\" alt=\"${title}\" src=\"${raw_url}\">"
else
echo "_Missing: \`${name}\`_"
fi
echo
} >> "${GITHUB_STEP_SUMMARY}"
}

{
echo "## Hosted Visual Screenshot Gallery"
echo
echo "- Published branch path: [\`${SCREENSHOT_BRANCH}/${RUN_PATH}\`](${branch_run_url})"
echo "- Workflow run: [${GITHUB_RUN_ID}](${run_url})"
echo "- Full evidence bundles remain attached as job artifacts."
echo
echo "> The thumbnails below are loaded from the dedicated \`${SCREENSHOT_BRANCH}\` branch. If GitHub does not render them inline, use the linked file or artifact bundle."
echo
} >> "${GITHUB_STEP_SUMMARY}"

add_image "macOS iTerm2" macos iterm2-window.png
add_image "Windows direct Sixel" windows windows-terminal-direct-sixel.png
add_image "Windows Terminal Sixel" windows windows-terminal-sixel.png
Loading