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
18 changes: 12 additions & 6 deletions .github/workflows/publish-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,31 @@ on:
types: [completed]
pull_request_target:
types: [closed]
issue_comment:
types: [created]
workflow_dispatch:

permissions:
contents: read

# Reconcile all open PRs on every run: Actions may coalesce pending runs.
concurrency:
group: quickdash-pages-publish
cancel-in-progress: false

jobs:
publish:
if: >-
github.event_name != 'issue_comment' ||
(github.event.issue.pull_request && startsWith(github.event.comment.body, '/deploy '))
# Only deployment requests enter the queue; ordinary/bot comments cannot
# replace pending deployments. Every publish reconciles all open PRs.
concurrency:
group: quickdash-pages-publish
cancel-in-progress: false
runs-on: ubuntu-24.04
permissions:
actions: read
contents: write
pages: write
id-token: write
checks: write
pull-requests: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
Expand Down Expand Up @@ -53,7 +59,7 @@ jobs:
- name: Publish dashboard and previews
id: deployment
uses: actions/deploy-pages@v5
- name: Link deployed previews from PR checks
- name: Link deployed previews on PRs
env:
GH_TOKEN: ${{ github.token }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
Expand Down
3 changes: 3 additions & 0 deletions OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# GitHub users trusted to auto-deploy previews and approve /deploy <commit-sha>.
jonabur
spyysalo
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Files opened here stay in your browser; they are not uploaded or included in lin
- Edit or add a self-contained eval file in [configs/evals/](configs/evals/), such as [polymath.yaml](configs/evals/polymath.yaml). Each file holds its scoring rules and language assignments together; the catalogue combines them automatically.
- Add weighting profiles to [configs/weights/](configs/weights/), or optional named eval sets to [configs/sets/](configs/sets/). Each directory has a `default.txt` choosing its startup selection. See [contributing configs](configs/README.md).

Use a pull request or GitHub’s **Add file → Upload files**. Changes on `main` trigger tests and a GitHub Pages rebuild. Successful PR builds get a separate review page: open **Details** on the PR’s **Pages preview** check, or use the [preview index](https://openeurollm.github.io/quickdash/pr-preview/). Previews update after successful builds and are removed when the PR closes. Invalid inputs leave the last successful page online. The repository, dashboard, and PR previews are public, so use browser imports for private comparisons.
Use a pull request or GitHub’s **Add file → Upload files**. Changes on `main` trigger tests and a GitHub Pages rebuild. PRs authored by a user in [OWNERS](OWNERS) get previews automatically after checks pass. For other authors, the bot supplies a copyable `/deploy <commit-sha>` command that an OWNER can post to approve that commit. Later commits require new approval. Click **Open preview** in the bot comment on the PR conversation; CI updates that same comment with the built commit. The **Pages preview** check and [preview index](https://openeurollm.github.io/quickdash/pr-preview/) also link to it. Previews are removed when the PR closes. The repository, dashboard, and PR previews are public, so use browser imports for private comparisons.

The [build workflow](.github/workflows/pages.yml) checks and packages the dashboard, fictional demo, and licenses. The [Pages publisher](.github/workflows/publish-pages.yml) combines the main dashboard with previews at `pr-preview/pr-<number>/`. Repository maintainers configure **Settings → Pages → Source → GitHub Actions**. Check the repository’s **Actions** tab if an update fails to appear; see [publishing and previews](docs/development.md#publish-through-github-pages).

Expand Down
12 changes: 10 additions & 2 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,23 @@ The [workflow](../.github/workflows/pages.yml) runs public tests on pull request

After tests pass, it builds the shared dashboard and a separate fictional demo. When `results/` has no CSVs, the shared page embeds `examples/sample-evals.csv`; real shared CSVs take precedence. The sample also runs through both engines in CI for all shipped weighting profiles, eval sets, and aggregation modes, with complete and mismatched coverage. See [contributor requirements](../AGENTS.md). Only `output/site/` is uploaded as the build artifact: `index.html`, `demo.html`, and license files. Build artifacts are retained for 30 days. The repository root and private local output are not published as the site.

In repository **Settings → Pages**, select **GitHub Actions** as the source. Keep the `github-pages` environment restricted to `main`. The [publisher workflow](../.github/workflows/publish-pages.yml) runs after build completions, when a PR closes, or through **Run workflow**. It executes the publisher script from the default branch and uses successful build artifacts as static data. It never checks out or executes PR code with publishing permissions, including for fork PRs. The build workflow keeps read-only repository access.
In repository **Settings → Pages**, select **GitHub Actions** as the source. Keep the `github-pages` environment restricted to `main`. The [publisher workflow](../.github/workflows/publish-pages.yml) runs after build completions, when a PR closes, on `/deploy <commit-sha>` PR comments, or through **Run workflow**. It executes the publisher script from the default branch and uses successful build artifacts as static data. It never checks out or executes PR code with publishing permissions, including for fork PRs. The build workflow keeps read-only repository access.

[OWNERS](../OWNERS) lists GitHub logins trusted to auto-deploy their PRs and approve other authors' previews. The initial owners are `jonabur` and `spyysalo`. The publisher reads OWNERS from its trusted default-branch checkout; changes to OWNERS within a PR cannot grant that PR access. Logins are case-insensitive, one per line, with optional `#` comments. An empty or malformed list fails publishing.

For another author, the bot explains why it did not auto-deploy and includes a complete `/deploy <40-character-commit-sha>` command in a code block. An OWNER can copy it into a new comment; no manual hash entry is needed. Only a standalone command written by a current OWNER and matching the exact commit grants approval. Bare `/deploy`, partial hashes, quoted commands, and commands from non-owners do not grant access. Successful checks are still required. When that commit is deployed, the bot adds a rocket reaction to the owner's command. Reactions alone do not approve deployment: GitHub Actions has no reaction-created trigger.

Approval is read from PR comments on every reconciliation, so coalesced workflow events cannot lose a command. A new push needs a new approval. A previously approved preview can stay available while the new head awaits approval; the comment labels the older build. Removing an owner or deleting their approval revokes access on the next reconciliation, including previously deployed content that no longer has valid authorization. Use **Run workflow** to apply a revocation immediately. Ordinary comments do not enter the deployment concurrency queue.

The publisher deploys one combined site:

- `/quickdash/` serves the latest successful main build.
- `/quickdash/pr-preview/pr-<number>/` serves that PR’s latest published successful build.
- `/quickdash/pr-preview/` lists open PRs, preview links, and the exact built commits. It labels a retained preview as **Previous successful build** when the current PR head has no successful build yet.

After deployment succeeds, a **Pages preview** check on each current built PR commit links directly to its preview. No PR comments are posted. Closing or merging a PR removes its directory on the next publisher run. A failed main build preserves production; a failed PR build preserves its previous preview. Review both the ordinary `build` check and the built commit before assessing a preview. Previews are public and share the Pages origin with the main dashboard.
After deployment succeeds, the publisher creates or updates one bot comment in each PR conversation with a prominent **Open preview** link and the built commit, or the owner-approval instructions when deployment is blocked. It reuses the comment without writing when the text is unchanged, and only edits comments owned by `github-actions[bot]` with the publisher’s hidden marker. A preview from an older successful build is labelled explicitly. Closing or merging a PR removes its directory and changes its existing comment to **Preview closed** after deployment succeeds; pending comment cleanup persists across failed deployments and retries. Reopening the PR lets the next successful deployment reuse the comment.

A **Pages preview** check on each current authorized, built PR commit also includes an **Open preview** link in its summary. A failed main build preserves production; a failed PR build preserves its previous authorized preview. Review both the ordinary `build` check and the built commit before assessing a preview. Previews are public and share the Pages origin with the main dashboard. Authorizing a preview means trusting its browser code: read-only data does not stop JavaScript from misleading users or reading same-origin browser storage and files a user imports into that page. The authorization gate is not a browser sandbox. The trusted publisher has `pull-requests: write` for comments and acknowledgment reactions; PR build jobs retain read-only permissions.

Generated files and their source run/commit identifiers persist on the `pages-content` branch, created automatically by the first publisher run. This is storage for the Actions publisher; **do not change Pages to deploy from this branch**. The stored files keep published previews available after their source artifacts expire. Every publisher run reconciles all open PRs and successful main builds, and publishing is serialized so concurrent builds cannot overwrite each other’s previews. Run **Publish dashboard and PR previews** manually to retry a failed deployment or reconcile missed updates. The workflow must be on `main` before automatic previews can run; existing successful artifacts can be picked up during that first deployment.

Expand Down
Loading