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
59 changes: 59 additions & 0 deletions .github/workflows/deploy-public-site.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Deploy Public Site

on:
push:
branches: [main]
paths:
- ".github/workflows/deploy-public-site.yml"
- "website/**"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: secopsai-public-site-production
cancel-in-progress: false

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Set up Node.js 22
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
with:
node-version: "22"

- name: Deploy reviewed website directory
env:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
npx --yes wrangler@4.114.0 pages deploy website \
--project-name website \
--branch main \
--commit-hash "${GITHUB_SHA}" \
--commit-message "Deploy SecOpsAI public site ${GITHUB_SHA}"

- name: Verify public installer contents
run: |
set -euo pipefail
verify_installer() {
installer="$1"
marker="$2"
output="${RUNNER_TEMP}/${installer}"
curl -fsSL --retry 8 --retry-all-errors --retry-delay 5 \
"https://secopsai.dev/${installer}?release=${GITHUB_SHA}" \
-o "$output"
if [ "$(sed -n '1p' "$output")" != "#!/bin/sh" ]; then
echo "${installer} did not return a POSIX shell installer" >&2
exit 1
fi
grep -F "$marker" "$output" >/dev/null

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Compare fetched installers with this deployment

When an installer changes without changing these release markers—for example, a fix to install.sh while remaining on v1.0.0—the previous deployment has the same shebang and marker, so this check succeeds even if the apex domain still serves stale content or points at the wrong deployment. The SHA query only makes the request URL unique; it does not prove the response came from that commit. Compare the downloaded body with website/${installer} or its digest instead.

Useful? React with 👍 / 👎.

}
verify_installer "install.sh" 'SECOPSAI_INSTALL_REF:-v1.0.0'
verify_installer "install-hermes.sh" 'MIN_VERSION="0.18.2"'
5 changes: 4 additions & 1 deletion docs/deployment-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ copies under `docs/`:
- `website/install-hermes.sh` and `www/install-hermes.sh`

This is the recommended path because the existing Cloudflare Pages Git
deployments require no separate Worker credential or manual route update.
deployment requires no separate Worker route. The repository also runs
`.github/workflows/deploy-public-site.yml` after relevant `main` changes. That
workflow publishes the reviewed `website/` directory explicitly and verifies
the contents of both public installer endpoints before it succeeds.

You have two fallback options if the apex site is moved away from these Pages
projects.
Expand Down
4 changes: 4 additions & 0 deletions tests/test_hermes_installers.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ def test_public_hermes_installer_and_worker_route_are_wired() -> None:
standard = (ROOT / "docs" / "install.sh").read_text(encoding="utf-8")
assert (ROOT / "website" / "install.sh").read_text(encoding="utf-8") == standard
assert (ROOT / "www" / "install.sh").read_text(encoding="utf-8") == standard
deployment = (ROOT / ".github" / "workflows" / "deploy-public-site.yml").read_text(encoding="utf-8")
assert "wrangler@4.114.0 pages deploy website" in deployment
assert "verify_installer \"install-hermes.sh\"" in deployment
assert "CLOUDFLARE_API_TOKEN" in deployment


def test_tracked_website_copies_are_identical_and_contain_hermes_tab() -> None:
Expand Down
Loading