Skip to content

Commit bfcb511

Browse files
committed
pdages
1 parent 2fcfd3b commit bfcb511

6 files changed

Lines changed: 125 additions & 25 deletions

File tree

.github/workflows/gh-pages-deploy.yml

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
name: Deploy GitHub Pages
22

33
on:
4-
release:
5-
types: [published]
6-
push:
7-
branches:
8-
- main
9-
paths:
10-
- 'gh-pages/**'
11-
- '.github/workflows/gh-pages-deploy.yml'
124
workflow_dispatch:
135

146
permissions:
@@ -35,30 +27,42 @@ jobs:
3527
GH_TOKEN: ${{ github.token }}
3628
run: |
3729
release_info=$(gh api repos/${{ github.repository }}/releases/latest 2>/dev/null || echo '{}')
30+
releases_url="https://github.com/${{ github.repository }}/releases"
3831
3932
if [[ "$release_info" == "{}" ]] || [[ -z "$(echo "$release_info" | jq -r '.tag_name // empty')" ]]; then
40-
echo "No releases found, using default values"
41-
echo "version=1.0.0" >> "$GITHUB_OUTPUT"
42-
echo "publish_date=$(date +%Y-%m-%d)" >> "$GITHUB_OUTPUT"
43-
echo "macos_url=https://github.com/${{ github.repository }}/releases" >> "$GITHUB_OUTPUT"
44-
echo "windows_url=https://github.com/${{ github.repository }}/releases" >> "$GITHUB_OUTPUT"
45-
echo "linux_url=https://github.com/${{ github.repository }}/releases" >> "$GITHUB_OUTPUT"
33+
echo "No releases found, using the repo version prefix"
34+
version_prefix="$(sed -n "s:.*<DotPilotVersionPrefix[^>]*>\\([^<]*\\)</DotPilotVersionPrefix>.*:\\1:p" ./Directory.Build.props | head -n 1)"
35+
if [[ -z "${version_prefix}" ]]; then
36+
version_prefix="0.0"
37+
fi
38+
39+
{
40+
echo "version=${version_prefix}"
41+
echo "publish_date=$(date +%Y-%m-%d)"
42+
echo "release_url=${releases_url}"
43+
echo "macos_url=${releases_url}"
44+
echo "windows_url=${releases_url}"
45+
echo "linux_url=${releases_url}"
46+
} >> "$GITHUB_OUTPUT"
4647
exit 0
4748
fi
4849
4950
version=$(echo "$release_info" | jq -r '.tag_name' | sed 's/^v//')
5051
publish_date=$(echo "$release_info" | jq -r '.published_at' | cut -d'T' -f1)
51-
echo "publish_date=${publish_date}" >> "$GITHUB_OUTPUT"
52-
echo "version=${version}" >> "$GITHUB_OUTPUT"
52+
release_url=$(echo "$release_info" | jq -r '.html_url // empty')
5353
5454
macos_url=$(echo "$release_info" | jq -r '.assets[] | select(.name | contains("macos")) | .browser_download_url' | head -n 1)
5555
windows_url=$(echo "$release_info" | jq -r '.assets[] | select(.name | contains("windows")) | .browser_download_url' | head -n 1)
5656
linux_url=$(echo "$release_info" | jq -r '.assets[] | select(.name | contains("linux")) | .browser_download_url' | head -n 1)
5757
58-
releases_url="https://github.com/${{ github.repository }}/releases/latest"
59-
echo "macos_url=${macos_url:-$releases_url}" >> "$GITHUB_OUTPUT"
60-
echo "windows_url=${windows_url:-$releases_url}" >> "$GITHUB_OUTPUT"
61-
echo "linux_url=${linux_url:-$releases_url}" >> "$GITHUB_OUTPUT"
58+
{
59+
echo "publish_date=${publish_date}"
60+
echo "version=${version}"
61+
echo "release_url=${release_url:-$releases_url}"
62+
echo "macos_url=${macos_url:-$releases_url}"
63+
echo "windows_url=${windows_url:-$releases_url}"
64+
echo "linux_url=${linux_url:-$releases_url}"
65+
} >> "$GITHUB_OUTPUT"
6266
6367
- name: Prepare Site
6468
run: |
@@ -69,6 +73,7 @@ jobs:
6973
cp ./gh-pages/robots.txt ./site/robots.txt
7074
7175
sed -i "s|{{VERSION}}|${{ steps.release.outputs.version }}|g" ./site/index.html
76+
sed -i "s|{{RELEASE_URL}}|${{ steps.release.outputs.release_url }}|g" ./site/index.html
7277
sed -i "s|{{MACOS_URL}}|${{ steps.release.outputs.macos_url }}|g" ./site/index.html
7378
sed -i "s|{{WINDOWS_URL}}|${{ steps.release.outputs.windows_url }}|g" ./site/index.html
7479
sed -i "s|{{LINUX_URL}}|${{ steps.release.outputs.linux_url }}|g" ./site/index.html

.github/workflows/release-publish.yml

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ jobs:
8080
timeout-minutes: 60
8181
needs:
8282
- prepare_release
83+
outputs:
84+
asset_name: ${{ steps.stage_asset.outputs.asset_name }}
8385
steps:
8486
- uses: actions/checkout@v6
8587
with:
@@ -133,18 +135,21 @@ jobs:
133135
-p:DotPilotBuildNumber=${{ needs.prepare_release.outputs.application_version }}
134136
135137
- name: Stage macOS Release Asset
138+
id: stage_asset
136139
shell: bash
137140
run: |
138141
mkdir -p ./artifacts/releases
139142
source_path="./DotPilot/bin/Release/net10.0-desktop/${{ steps.macos_rid.outputs.rid }}/publish/DotPilot.dmg"
140-
target_path="./artifacts/releases/dotpilot-${{ needs.prepare_release.outputs.release_version }}-${{ steps.macos_rid.outputs.asset_suffix }}.dmg"
143+
asset_name="dotpilot-${{ needs.prepare_release.outputs.release_version }}-${{ steps.macos_rid.outputs.asset_suffix }}.dmg"
144+
target_path="./artifacts/releases/${asset_name}"
141145
142146
if [[ ! -f "${source_path}" ]]; then
143147
echo "Expected macOS release asset was not produced: ${source_path}" >&2
144148
exit 1
145149
fi
146150
147151
cp "${source_path}" "${target_path}"
152+
echo "asset_name=${asset_name}" >> "$GITHUB_OUTPUT"
148153
149154
- name: Upload macOS Release Artifact
150155
uses: actions/upload-artifact@v7
@@ -160,6 +165,8 @@ jobs:
160165
timeout-minutes: 60
161166
needs:
162167
- prepare_release
168+
outputs:
169+
asset_name: ${{ steps.stage_asset.outputs.asset_name }}
163170
steps:
164171
- uses: actions/checkout@v6
165172
with:
@@ -190,17 +197,20 @@ jobs:
190197
-p:DotPilotBuildNumber=${{ needs.prepare_release.outputs.application_version }}
191198
192199
- name: Stage Windows Release Asset
200+
id: stage_asset
193201
shell: pwsh
194202
run: |
195203
New-Item -ItemType Directory -Force -Path .\artifacts\releases | Out-Null
196204
$sourcePath = ".\DotPilot\bin\Release\net10.0-desktop\win-x64\publish\DotPilot.exe"
197-
$targetPath = ".\artifacts\releases\dotpilot-${{ needs.prepare_release.outputs.release_version }}-windows-x64.exe"
205+
$assetName = "dotpilot-${{ needs.prepare_release.outputs.release_version }}-windows-x64.exe"
206+
$targetPath = ".\artifacts\releases\$assetName"
198207
199208
if (-not (Test-Path $sourcePath)) {
200209
throw "Expected Windows release asset was not produced: $sourcePath"
201210
}
202211
203212
Copy-Item $sourcePath $targetPath -Force
213+
"asset_name=$assetName" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
204214
205215
- name: Upload Windows Release Artifact
206216
uses: actions/upload-artifact@v7
@@ -216,6 +226,8 @@ jobs:
216226
timeout-minutes: 60
217227
needs:
218228
- prepare_release
229+
outputs:
230+
asset_name: ${{ steps.stage_asset.outputs.asset_name }}
219231
steps:
220232
- uses: actions/checkout@v6
221233
with:
@@ -260,18 +272,21 @@ jobs:
260272
sudo chown -R "$USER:$USER" ./bin/Release/net10.0-desktop/linux-x64
261273
262274
- name: Stage Linux Release Asset
275+
id: stage_asset
263276
shell: bash
264277
run: |
265278
mkdir -p ./artifacts/releases
266279
source_path="$(find ./DotPilot/bin/Release/net10.0-desktop/linux-x64/publish -maxdepth 1 -type f -name '*.snap' | sort | head -n 1)"
267-
target_path="./artifacts/releases/dotpilot-${{ needs.prepare_release.outputs.release_version }}-linux-x64.snap"
280+
asset_name="dotpilot-${{ needs.prepare_release.outputs.release_version }}-linux-x64.snap"
281+
target_path="./artifacts/releases/${asset_name}"
268282
269283
if [[ -z "${source_path}" || ! -f "${source_path}" ]]; then
270284
echo "Expected Linux snap release asset was not produced." >&2
271285
exit 1
272286
fi
273287
274288
cp "${source_path}" "${target_path}"
289+
echo "asset_name=${asset_name}" >> "$GITHUB_OUTPUT"
275290
276291
- name: Upload Linux Release Artifact
277292
uses: actions/upload-artifact@v7
@@ -396,3 +411,75 @@ jobs:
396411
fi
397412
398413
"${release_command[@]}"
414+
415+
publish_site:
416+
name: Publish Release Website
417+
runs-on: ubuntu-latest
418+
needs:
419+
- prepare_release
420+
- publish_macos
421+
- publish_windows
422+
- publish_linux
423+
- create_release
424+
permissions:
425+
contents: read
426+
pages: write
427+
id-token: write
428+
steps:
429+
- uses: actions/checkout@v6
430+
with:
431+
fetch-depth: 0
432+
ref: ${{ github.sha }}
433+
434+
- name: Prepare Release Website
435+
shell: bash
436+
env:
437+
MACOS_ASSET_NAME: ${{ needs.publish_macos.outputs.asset_name }}
438+
WINDOWS_ASSET_NAME: ${{ needs.publish_windows.outputs.asset_name }}
439+
LINUX_ASSET_NAME: ${{ needs.publish_linux.outputs.asset_name }}
440+
RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }}
441+
RELEASE_VERSION: ${{ needs.prepare_release.outputs.release_version }}
442+
REPOSITORY: ${{ github.repository }}
443+
run: |
444+
mkdir -p ./site
445+
446+
cp ./gh-pages/index.html ./site/index.html
447+
cp ./gh-pages/sitemap.xml ./site/sitemap.xml
448+
cp ./gh-pages/robots.txt ./site/robots.txt
449+
450+
release_url="https://github.com/${REPOSITORY}/releases/tag/${RELEASE_TAG}"
451+
macos_url="https://github.com/${REPOSITORY}/releases/download/${RELEASE_TAG}/${MACOS_ASSET_NAME}"
452+
windows_url="https://github.com/${REPOSITORY}/releases/download/${RELEASE_TAG}/${WINDOWS_ASSET_NAME}"
453+
linux_url="https://github.com/${REPOSITORY}/releases/download/${RELEASE_TAG}/${LINUX_ASSET_NAME}"
454+
publish_date="$(date -u +%Y-%m-%d)"
455+
456+
sed -i "s|{{VERSION}}|${RELEASE_VERSION}|g" ./site/index.html
457+
sed -i "s|{{RELEASE_URL}}|${release_url}|g" ./site/index.html
458+
sed -i "s|{{MACOS_URL}}|${macos_url}|g" ./site/index.html
459+
sed -i "s|{{WINDOWS_URL}}|${windows_url}|g" ./site/index.html
460+
sed -i "s|{{LINUX_URL}}|${linux_url}|g" ./site/index.html
461+
sed -i "s|{{PUBLISH_DATE}}|${publish_date}|g" ./site/sitemap.xml
462+
463+
- name: Setup Pages
464+
uses: actions/configure-pages@v5
465+
466+
- name: Upload Pages Artifact
467+
uses: actions/upload-pages-artifact@v4
468+
with:
469+
path: ./site
470+
471+
deploy_site:
472+
name: Deploy Release Website
473+
runs-on: ubuntu-latest
474+
needs:
475+
- publish_site
476+
permissions:
477+
pages: write
478+
id-token: write
479+
environment:
480+
name: github-pages
481+
url: ${{ steps.deployment.outputs.page_url }}
482+
steps:
483+
- name: Deploy to GitHub Pages
484+
id: deployment
485+
uses: actions/deploy-pages@v4

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ For this app:
208208
- meaningful GitHub review comments must be evaluated and fixed when they still apply even if the original PR was closed; closed review threads are not a reason to ignore valid engineering feedback
209209
- PR bodies for issue-backed work must use GitHub closing references such as `Closes #14` so merged work closes the tracked issue automatically
210210
- the release workflow must run automatically on pushes to `main`, build desktop apps, and publish the GitHub Release without requiring a manual dispatch
211+
- the release path must also publish the GitHub Pages site after the GitHub Release is created, and every site version or download reference must resolve from that release's actual version and assets instead of fallback literals such as `1.0.0`
211212
- repository rules for `main` must keep an explicit org-admin bypass path for required status checks so repository administrators can perform direct emergency or operator-owned pushes without deadlocking the branch policy
212213
- after changing GitHub rulesets, workflows, or release packaging, verify against the specific live blocked operation or failing run instead of assuming the policy or YAML change solved the issue
213214
- desktop app build or publish jobs must use native runners for their target OS: macOS artifacts on macOS runners, Windows artifacts on Windows runners, and Linux artifacts on Linux runners

docs/ADR/ADR-0002-split-github-actions-build-and-release.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ We will split GitHub Actions into two explicit workflows:
3535
- publishes desktop release assets for macOS, Windows, and Linux as real packaged outputs instead of raw publish-folder archives
3636
- uses `.dmg` for macOS, a self-contained single-file `.exe` for Windows, and `.snap` for Linux
3737
- creates the GitHub Release
38+
- publishes the `gh-pages` website after the GitHub Release is created, using the same resolved release version and release asset URLs
3839
- prepends repo-owned feature summaries and feature-doc links to GitHub-generated release notes
3940

4041
## Decision Diagram
@@ -50,6 +51,7 @@ flowchart LR
5051
Version["Version resolved from DotPilot.csproj prefix + CI build number"]
5152
Publish["Desktop packaged assets (.dmg, .exe, .snap)"]
5253
GitHubRelease["GitHub Release with feature notes"]
54+
Website["GitHub Pages site"]
5355
5456
Change --> Validation
5557
Validation --> Quality
@@ -59,6 +61,7 @@ flowchart LR
5961
Release --> Version
6062
Release --> Publish
6163
Release --> GitHubRelease
64+
Release --> Website
6265
```
6366

6467
## Alternatives Considered
@@ -90,6 +93,7 @@ That makes release quality depend on operator memory instead of repo-owned histo
9093
- Desktop publish artifacts move to the workflow that actually needs them.
9194
- Release notes now combine GitHub-generated notes with repo-owned feature context.
9295
- Release numbers stay predictable: humans own the major/minor prefix in source and CI owns the last segment.
96+
- The public website now updates in the same release path as the desktop artifacts, so version and download links stay in sync with the published release.
9397

9498
### Negative
9599

docs/Architecture.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ This file is the required start-here architecture map for non-trivial tasks.
1414
- **Extraction rule:** large non-UI features start in `DotPilot.Core`, but once a slice becomes big enough to need its own boundary, it should move into a dedicated DLL that references `DotPilot.Core`, while the desktop app references that feature DLL directly.
1515
- **Solution-shape rule:** solution folders may group projects by stable categories such as libraries and tests, but extracted subsystems must still keep their own files, namespaces, and project-local rules inside their real project directory.
1616
- **Verification boundary:** [../DotPilot.Tests/](../DotPilot.Tests/) covers caller-visible runtime, persistence, contract, and view-model flows through public boundaries. [../DotPilot.UITests/](../DotPilot.UITests/) covers the desktop operator journey from provider setup to streaming chat.
17+
- **Release website rule:** the desktop release path owns the GitHub Pages publish for [../gh-pages/](../gh-pages/); the site version badge and release download links must resolve from the same CI-derived release version and assets as the GitHub Release.
1718

1819
## Scoping
1920

@@ -30,13 +31,15 @@ flowchart LR
3031
Root["dotPilot repository root"]
3132
Governance["AGENTS.md"]
3233
Architecture["docs/Architecture.md"]
34+
Site["gh-pages static website"]
3335
Ui["DotPilot Uno desktop shell"]
3436
Core["DotPilot.Core contracts + shared application code"]
3537
Unit["DotPilot.Tests"]
3638
UiTests["DotPilot.UITests"]
3739
3840
Root --> Governance
3941
Root --> Architecture
42+
Root --> Site
4043
Root --> Ui
4144
Root --> Core
4245
Root --> Unit

gh-pages/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
"operatingSystem": ["Windows", "macOS", "Linux"],
7878
"description": "Open source local agent orchestrator built with C# and .NET. Run multiple AI agents locally, build workflows, connect to any AI provider.",
7979
"url": "https://dotpilot.managed-code.com",
80-
"downloadUrl": "https://github.com/managedcode/dotPilot/releases/latest",
80+
"downloadUrl": "{{RELEASE_URL}}",
8181
"softwareVersion": "{{VERSION}}",
8282
"author": {
8383
"@type": "Organization",
@@ -750,7 +750,7 @@
750750
<div class="hero-layout">
751751
<div class="hero-left">
752752
<h1>Your <span class="highlight">agents.</span> Your <span class="bold">stack.</span> Your rules.</h1>
753-
<a href="https://github.com/managedcode/dotPilot/releases/latest" class="btn btn-dark">
753+
<a href="{{RELEASE_URL}}" class="btn btn-dark">
754754
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
755755
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
756756
<polyline points="7 10 12 15 17 10"/>

0 commit comments

Comments
 (0)