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
1 change: 1 addition & 0 deletions .github/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ including the PR title format and the Go checks that CI gates on, are in the roo
| `release-binaries.yaml` | Tag push (`v*`), manual; push to main publishes the main-latest channel when `MAIN_CHANNEL_ENABLED` is set | Release tarballs — see [Release binaries](#release-binaries) |
| `pr-verifier.yml` | PR | PR title check |
| `spellcheck_action.yml` | PR | Spellcheck on markdown files — **disabled** (`if: false`) |
| `site-dispatch.yaml` | Push to main on `scripts/install.sh`, manual | Sends `docs-updated` to `rossoctl/.github`, so the site's `/cortex/install.sh` copy updates in minutes, not at its daily schedule. Needs the `SITE_DISPATCH_TOKEN` secret; without it, a warning only |

Also: `release-smoke-linux.yaml`, `dependabot-tidy.yml`, `install-stats.yaml`, `project.yml`, `self-assign.yml`, `stale.yaml`.

Expand Down
101 changes: 101 additions & 0 deletions .github/workflows/site-dispatch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Site dispatch: tell the website to rebuild when the installer changes here.
#
# The one-liner `curl -fsSL https://www.rossoctl.dev/cortex/install.sh | sh`
# runs a copy of scripts/install.sh that the website in rossoctl/.github keeps.
# Its build (npm run sync-docs) copies the file from this repository's main.
#
# Without this workflow, the site copies the installer only on its daily 06:17
# UTC schedule, which GitHub can start hours late. Then a new installer option
# fails as "unknown option" for up to a day after the merge (install.sh --praxis
# on 2026-11-10). This workflow sends the repository_dispatch event that the
# site's "Deploy site to Pages" workflow already listens for (type:
# docs-updated), so the site has the new installer a few minutes after the
# merge. rossoctl/rossoctl sends the same event for its docs.
#
# ONE-TIME SETUP: the secret SITE_DISPATCH_TOKEN.
# GITHUB_TOKEN is scoped to this repository, so it cannot dispatch to another
# one. Create a fine-grained personal access token, or a GitHub App token,
# with "Contents: read and write" on rossoctl/.github ONLY, and store it here
# as the repository secret SITE_DISPATCH_TOKEN:
#
# gh secret set SITE_DISPATCH_TOKEN --repo rossoctl/cortex
#
# Until that secret exists, this workflow gives a warning and exits 0. It
# does not fail a merge, and the site's daily schedule still copies the file.
name: Site dispatch

on:
push:
branches: [main]
paths:
# The only file the site copies from this repository.
- "scripts/install.sh"
workflow_dispatch: {}

permissions:
contents: read

# One dispatch at a time. A burst of merges then gives one rebuild of the site.
concurrency:
group: site-dispatch
cancel-in-progress: false

jobs:
dispatch:
name: Ask rossoctl/.github to rebuild
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Send repository_dispatch to rossoctl/.github
id: dispatch
env:
GH_TOKEN: ${{ secrets.SITE_DISPATCH_TOKEN }}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

suggestion: repository_dispatch needs Contents: write on rossoctl/.github, so this secret can also push to the repo that serves /cortex/install.sh, the file people pipe into sh. As written, any job in this repo can read the secret. A write-access user can run workflow_dispatch (or push a workflow file) on any branch, and that branch's copy of this workflow gets the token. You could put the secret in a deployment environment (for example site-dispatch) that allows only main, and add environment: site-dispatch to the job. The token then reaches only workflow files on main. This is not a regression: it is the same pattern as rossoctl/rossoctl's docs-dispatch.yaml. A GitHub App token limited to rossoctl/.github would also make the token short-lived.

SHA: ${{ github.sha }}
ACTOR: ${{ github.actor }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
set -euo pipefail

if [ -z "${GH_TOKEN}" ]; then
echo "notified=false" >> "$GITHUB_OUTPUT"
msg="The website was not notified. It copies the installer on its daily 06:17 UTC"
msg="${msg} schedule. See the setup note in this workflow file."
echo "::warning title=SITE_DISPATCH_TOKEN is not set::${msg}"
exit 0
fi

echo "Dispatching docs-updated for ${SHA} to rossoctl/.github"

# The receiver is the "Deploy site to Pages" workflow in rossoctl/.github
# (on: repository_dispatch, types: [docs-updated]). client_payload only
# records which commit in this repository caused the rebuild.
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
repos/rossoctl/.github/dispatches \
-f event_type=docs-updated \
-f "client_payload[source_repo]=${GITHUB_REPOSITORY}" \
-f "client_payload[sha]=${SHA}" \
-f "client_payload[actor]=${ACTOR}" \
-f "client_payload[run_url]=${RUN_URL}"

echo "notified=true" >> "$GITHUB_OUTPUT"
echo "Dispatched. The site build runs at:"
echo "https://github.com/rossoctl/.github/actions/workflows/deploy.yaml"

- name: Summary
if: always()
env:
NOTIFIED: ${{ steps.dispatch.outputs.notified }}
run: |
{
echo "### Site dispatch"
echo ""
if [ "${NOTIFIED}" = "true" ]; then
echo "Sent \`docs-updated\` to rossoctl/.github. The site copies"
echo "\`scripts/install.sh\` from this commit."
else
echo "\`SITE_DISPATCH_TOKEN\` is not set, so the site was not notified."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: Because of if: always(), this branch also runs when the token is set but gh api fails (expired token, 403/404, network). notified is then unset, and the summary says "SITE_DISPATCH_TOKEN is not set", which sends the reader to the wrong cause. Wording like "The site was not notified (see the dispatch step)" would cover both cases. The dispatch step's own failure is still visible.

echo "It copies the installer on its daily 06:17 UTC schedule."
fi
} >> "$GITHUB_STEP_SUMMARY"
Loading