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
117 changes: 114 additions & 3 deletions .github/workflows/windows-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
outputs:
version: ${{ steps.version.outputs.version }}
artifact-name: ${{ steps.artifact.outputs.name }}
asset-base: ${{ steps.artifact.outputs.asset-base }}

steps:
- name: Checkout
Expand Down Expand Up @@ -80,15 +81,16 @@ jobs:
run: |
$safeVersion = "${{ steps.version.outputs.version }}" -replace '[^A-Za-z0-9._-]', '-'
"name=docsight-desktop-preview-win64-$safeVersion" >> $env:GITHUB_OUTPUT
"asset-base=DOCSight-Desktop-Preview-win64-$safeVersion" >> $env:GITHUB_OUTPUT

- name: Upload desktop artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ steps.artifact.outputs.name }}
if-no-files-found: error
path: |
packaging/windows/dist/DOCSight-Desktop-Preview-win64-*.zip
packaging/windows/dist/DOCSight-Desktop-Preview-win64-*.zip.sha256
packaging/windows/dist/${{ steps.artifact.outputs.asset-base }}.zip
packaging/windows/dist/${{ steps.artifact.outputs.asset-base }}.zip.sha256

attach-release-assets:
if: github.event_name == 'release'
Expand All @@ -108,4 +110,113 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ github.event.release.tag_name }}
run: gh release upload "$TAG_NAME" --repo "$GITHUB_REPOSITORY" release-assets/*.zip release-assets/*.sha256 --clobber
ASSET_BASE: ${{ needs.build.outputs.asset-base }}
run: |
gh release upload "$TAG_NAME" \
--repo "$GITHUB_REPOSITORY" \
"release-assets/$ASSET_BASE.zip" \
"release-assets/$ASSET_BASE.zip.sha256" \
--clobber

- name: Verify published release assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ github.event.release.tag_name }}
EXPECTED_ZIP: ${{ needs.build.outputs.asset-base }}.zip
EXPECTED_SHA256: ${{ needs.build.outputs.asset-base }}.zip.sha256
run: |
max_attempts=3
release_assets_read=0
for ((attempt = 1; attempt <= max_attempts; attempt++)); do
if release_assets_output="$(
gh release view "$TAG_NAME" \
--repo "$GITHUB_REPOSITORY" \
--json assets \
--jq '.assets[].name'
)"; then
if [[ -n "$release_assets_output" ]]; then
release_assets_read=1
break
fi
failure_message="Published release returned no assets."
else
failure_message="Unable to read published release assets."
fi

if (( attempt < max_attempts )); then
echo "::warning::$failure_message Retrying ($attempt/$max_attempts)."
sleep "$((2 ** attempt))"
fi
done
if (( release_assets_read == 0 )); then
echo "::error::$failure_message Failed after $max_attempts attempts."
exit 1
fi

mapfile -t release_assets <<< "$release_assets_output"
expected_zip_count=0
expected_sha256_count=0
unexpected_preview_assets=0
for asset in "${release_assets[@]}"; do
case "$asset" in
"$EXPECTED_ZIP")
((expected_zip_count += 1))
;;
"$EXPECTED_SHA256")
((expected_sha256_count += 1))
;;
*)
asset_lowercase="${asset,,}"
case "$asset_lowercase" in
docsight-desktop-preview-win64-*)
echo "::error::Published release contains unexpected Windows Preview asset: $asset"
unexpected_preview_assets=1
;;
esac
;;
esac
done

if (( expected_zip_count != 1 )); then
echo "::error::Published release must contain exactly one expected Windows Preview ZIP: $EXPECTED_ZIP"
exit 1
fi
if (( expected_sha256_count != 1 )); then
echo "::error::Published release must contain exactly one expected Windows Preview checksum: $EXPECTED_SHA256"
exit 1
fi
if (( unexpected_preview_assets != 0 )); then
exit 1
fi

verification_dir="$(mktemp -d)"
trap 'rm -rf -- "$verification_dir"' EXIT
if ! gh release download "$TAG_NAME" \
--repo "$GITHUB_REPOSITORY" \
--dir "$verification_dir" \
--pattern "$EXPECTED_ZIP" \
--pattern "$EXPECTED_SHA256"; then
echo "::error::Unable to download the expected published Windows Preview assets."
exit 1
fi

zip_path="$verification_dir/$EXPECTED_ZIP"
checksum_path="$verification_dir/$EXPECTED_SHA256"
if [[ ! -f "$zip_path" || ! -f "$checksum_path" ]]; then
echo "::error::Downloaded Windows Preview assets are incomplete."
exit 1
fi

checksum_line="$(head -n 1 -- "$checksum_path")"
read -r expected_hash _ <<< "$checksum_line"
if [[ ! "$expected_hash" =~ ^[[:xdigit:]]{64}$ ]]; then
echo "::error::Published Windows Preview checksum is empty or invalid."
exit 1
fi

actual_hash_output="$(sha256sum -- "$zip_path")"
read -r actual_hash _ <<< "$actual_hash_output"
if [[ "${actual_hash,,}" != "${expected_hash,,}" ]]; then
echo "::error::Published Windows Preview ZIP does not match its published checksum."
exit 1
fi
22 changes: 16 additions & 6 deletions CODE_SIGNING.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,26 @@ with the Windows SDK SignTool:
signtool verify /pa /v .\DOCSight\DOCSight.exe
```

Until then, preview artifacts are unsigned. Download the ZIP and its
corresponding `.sha256` file from the same release, calculate the ZIP's SHA-256
digest, and compare the values before use:
Until then, preview artifacts are unsigned. Each Windows Preview ZIP on the
official release has a corresponding `.sha256` asset for an optional advanced
integrity check. Download both files from the same release, then run this
optional PowerShell comparison from the folder containing them:

```powershell
Get-FileHash -Algorithm SHA256 .\DOCSight-Desktop-Preview-win64-<version>.zip
$zip = ".\DOCSight-Desktop-Preview-win64-<version>.zip"
$checksumFile = "$zip.sha256"
$checksumText = Get-Content -LiteralPath $checksumFile -Raw
$expectedHash = if ([string]::IsNullOrWhiteSpace($checksumText)) { "" } else { ($checksumText.Trim() -split '\s+', 2)[0] }
$actualHash = (Get-FileHash -LiteralPath $zip -Algorithm SHA256).Hash
$checksumMatches = [string]::Equals($actualHash, $expectedHash, [System.StringComparison]::OrdinalIgnoreCase)
$checksumMatches
```

A matching checksum verifies download integrity against the published checksum.
It does not provide publisher authentication or replace a code signature.
The final command returns `True` only when the ZIP hash matches the first hash
value in the checksum file. SHA-256 is hexadecimal, so uppercase and lowercase
letters represent the same hash value and are compared case-insensitively. A
matching checksum verifies download integrity against the published checksum.
It does not verify publisher identity or replace a code signature.

## Privacy and security reporting

Expand Down
4 changes: 2 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ Covers Docker Run, Docker Compose, Portainer, Synology NAS, Unraid, updating, an

| If you want to... | Start here |
|---|---|
| Quickly try DOCSight on a Windows PC without Docker | [Desktop Preview for Windows](docs/windows-desktop-preview.md) |
| Quickly try DOCSight on a Windows PC without Docker | [Download the portable Desktop Preview](https://github.com/itsDNNS/docsight/releases/latest), then read the [usage notes](docs/windows-desktop-preview.md) |
| Monitor your connection continuously on Windows | [Windows Docker Desktop quick start](docs/windows-quick-start.md) |

On Windows 10/11, the normal 24/7 monitoring path is Docker Desktop. Start with the [Windows quick start](docs/windows-quick-start.md) when you want the supported Docker path. The Desktop Preview is a portable tryout build and is not intended for always-on collection.
On Windows 10/11, the normal 24/7 monitoring path is Docker Desktop. Start with the [Windows quick start](docs/windows-quick-start.md) when you want the supported Docker path. The unsigned Desktop Preview is a portable tryout build published through GitHub Releases and is not intended for always-on collection.

If setup or collection does not behave as expected, run the passive local doctor inside the same container before collecting manual environment details:

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<p align="center">
<a href="https://itsdnns.github.io/docsight/">Product page</a>&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="#get-started">Get Started</a>&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="https://github.com/itsDNNS/docsight/releases/latest">Windows Preview</a>&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="#supported-hardware">Supported Hardware</a>&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="https://github.com/itsDNNS/docsight/wiki">Wiki</a>&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="DATA_CONTRACT.md">Data contract</a>&nbsp;&nbsp;&bull;&nbsp;&nbsp;
Expand Down Expand Up @@ -47,7 +48,7 @@

## Get Started

Start with the fastest path for your setup. On Windows 10/11, use the [Windows quick start](docs/windows-quick-start.md) for Docker Desktop checks, a PowerShell-safe command, and common startup fixes.
Start with the fastest path for your setup. On Windows 10/11, download the unsigned portable [Windows Desktop Preview from the latest release](https://github.com/itsDNNS/docsight/releases/latest) for a quick first look without Docker. For continuous monitoring, use the [Windows quick start](docs/windows-quick-start.md).

### Option 1: Try the demo

Expand Down
3 changes: 3 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
h1 { margin: 16px 0 18px; font-size: clamp(2.45rem, 5vw, 4.9rem); line-height: 1; letter-spacing: -0.07em; }
.lead { margin: 0; color: #d8e2f4; font-size: clamp(1.08rem, 2vw, 1.32rem); max-width: 670px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin: 30px 0 24px; }
.preview-boundary { flex: 0 0 100%; max-width: 670px; margin: 0; color: var(--soft); font-size: 0.9rem; }
.btn {
display: inline-flex;
align-items: center;
Expand Down Expand Up @@ -208,6 +209,8 @@ <h1>Your ISP says everything is fine. DOCSight shows the timeline.</h1>
<p class="lead">DOCSight records signal history, speed tests, latency, modem events and your own notes locally, so intermittent cable problems do not disappear into "looks fine from here".</p>
<div class="hero-actions">
<a class="btn primary" href="https://github.com/itsDNNS/docsight#option-1-try-the-demo">Try the demo</a>
<a class="btn" href="https://github.com/itsDNNS/docsight/releases/latest">Download Windows Preview</a>
<p class="preview-boundary">The Windows download is an unsigned portable Preview for short local tests. For continuous monitoring, use Docker on an always-on machine.</p>
<a class="btn" href="#proof">See example evidence</a>
<a class="btn" href="https://github.com/itsDNNS/docsight/wiki/Installation">Install DOCSight</a>
</div>
Expand Down
43 changes: 29 additions & 14 deletions docs/windows-desktop-preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,47 @@ Use it for first contact, demos, and short local tests. For reliable 24/7 monito
| Monitor your line continuously on a machine that stays awake, or after host restarts | Docker Desktop on an always-awake Windows PC, or another always-on Docker host |
| Run DOCSight on a NAS, mini-PC, server, or homelab | Docker |

## Download and verify
## Download and start

1. Open the DOCSight [GitHub releases](https://github.com/itsDNNS/docsight/releases).
2. Download the Windows Desktop Preview ZIP when a release provides one. The asset name uses this shape:
1. Open the [latest DOCSight release](https://github.com/itsDNNS/docsight/releases/latest).
2. Under **Assets**, download the unsigned portable Windows Desktop Preview ZIP. Its versioned name uses this shape:

```text
DOCSight-Desktop-Preview-win64-<version>.zip
```

3. Download the matching `.sha256` file.
4. In PowerShell, verify the checksum from the folder where you saved the files:
3. Extract the ZIP to a folder such as `Downloads\DOCSight` or `C:\Tools\DOCSight`.
4. Start `DOCSight.exe`.

```powershell
Get-FileHash .\DOCSight-Desktop-Preview-win64-<version>.zip -Algorithm SHA256
Get-Content .\DOCSight-Desktop-Preview-win64-<version>.zip.sha256
```
You do not need a GitHub account for this download path. PowerShell and checksum verification are optional.

## Optional: verify download integrity

Each Windows Preview ZIP has a matching checksum asset named:

```text
DOCSight-Desktop-Preview-win64-<version>.zip.sha256
```

For an optional integrity check, download that file from the same GitHub release. In PowerShell, run these commands from the folder where you saved both files:

```powershell
$zip = ".\DOCSight-Desktop-Preview-win64-<version>.zip"
$checksumFile = "$zip.sha256"
$checksumText = Get-Content -LiteralPath $checksumFile -Raw
$expectedHash = if ([string]::IsNullOrWhiteSpace($checksumText)) { "" } else { ($checksumText.Trim() -split '\s+', 2)[0] }
$actualHash = (Get-FileHash -LiteralPath $zip -Algorithm SHA256).Hash
$checksumMatches = [string]::Equals($actualHash, $expectedHash, [System.StringComparison]::OrdinalIgnoreCase)
$checksumMatches
```

The hash values must match.
5. Extract the ZIP to a folder such as `Downloads\DOCSight` or `C:\Tools\DOCSight`.
6. Start `DOCSight.exe`.
The final command returns `True` only when the ZIP hash matches the first hash value in the checksum file. SHA-256 is hexadecimal, so uppercase and lowercase letters represent the same hash value and are compared case-insensitively. A matching SHA256 checksum verifies download integrity against the published checksum. It does not verify publisher identity and does not replace a code signature.

## First start and SmartScreen

The preview is a portable app. Early builds may be unsigned. Windows SmartScreen can therefore show an "unrecognized app" warning even when the checksum matches the release checksum.
The preview is a portable, unsigned app while signing provider onboarding is pending. Windows SmartScreen can therefore show an "unrecognized app" warning.

If you downloaded DOCSight from the official GitHub release and the SHA256 checksum matches, choose **More info** and then **Run anyway**.
If you downloaded DOCSight from the official GitHub release and choose to continue, select **More info** and then **Run anyway**.

DOCSight starts a local web app and opens your default browser. The address is local to your PC, normally similar to:

Expand Down
4 changes: 2 additions & 2 deletions docs/windows-quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ DOCSight has two Windows paths:

| If you want to... | Start here |
|---|---|
| Try DOCSight without Docker | [Desktop Preview for Windows](windows-desktop-preview.md) |
| Try DOCSight without Docker | [Download the portable Desktop Preview](https://github.com/itsDNNS/docsight/releases/latest), then read the [usage notes](windows-desktop-preview.md) |
| Monitor your connection continuously | Docker Desktop quick start below |

The Desktop Preview is a portable ZIP for demos and short local tryouts. For 24/7 monitoring, use Docker Desktop or another always-on Docker host.
The Desktop Preview is an unsigned portable ZIP for demos and short local tryouts. It is published through GitHub Releases. For 24/7 monitoring, use Docker Desktop or another always-on Docker host.

DOCSight runs on Windows through Docker Desktop for continuous monitoring. Docker Desktop provides the Linux container runtime and DOCSight keeps its data in a Docker volume.

Expand Down
5 changes: 3 additions & 2 deletions packaging/windows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ packaging/windows/dist/DOCSight-Desktop-Preview-win64-<version>.zip.sha256
```

Current preview artifacts are unsigned while provider onboarding is pending.
Downloaders should verify the preview ZIP against its published `.sha256` file.
The matching `.sha256` release asset is available for optional integrity checks.
See the [code signing policy](../../CODE_SIGNING.md) for the onboarding status,
intended release scope, and verification guidance.

Expand All @@ -87,7 +87,8 @@ The `Windows Desktop Preview` workflow builds the portable package on
`windows-latest`, smoke-tests the built `DOCSight.exe` against
`http://127.0.0.1:<port>/health`, and uploads the ZIP plus `.sha256` as workflow
artifacts. Published releases also receive the ZIP and checksum as release
assets.
assets. Workflow artifacts are CI evidence only. Users download the unsigned
portable Preview from [GitHub Releases](https://github.com/itsDNNS/docsight/releases/latest).

For local Windows smoke testing after a build:

Expand Down
Loading