Files
Neil 46b225e473 chore(links): point website, docs and download links at orca.dev (#41376)
The site now lives at orca.dev; the old onorca.dev and www.onorca.dev hosts
redirect there. Linking to orca.dev directly skips that redirect.

Only page links change. Service hosts, sign-in and relay endpoints stay as they are.
2026-11-11 21:50:37 -08:00

269 lines
9.7 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Docs site
on:
# Stable desktop releases are the production publication boundary. The
# release gate below excludes mobile and prerelease tags from this trigger.
release:
types: [published]
pull_request:
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
paths:
- 'docs/site/**'
- '.github/workflows/docs.yml'
workflow_dispatch:
inputs:
tag:
description: 'Stable desktop release tag to redeploy (vX.Y.Z)'
required: true
type: string
permissions:
contents: read
concurrency:
# Serialize production runs so a delayed older release cannot overwrite a
# newer deployment. PR checks may still run concurrently by pull request.
group: ${{ github.event_name == 'pull_request' && format('docs-pr-{0}', github.event.pull_request.number) || 'docs-production' }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
defaults:
run:
# The Vercel project is rooted at `.`; this package directory is the
# complete upload and build context.
working-directory: docs/site
jobs:
# This job deliberately has no deployment credentials and runs for every PR,
# including forks.
check:
name: Build and test
if: github.event_name == 'pull_request' && github.event.pull_request.draft != true
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout pull request
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Setup pnpm
uses: pnpm/setup@v2
with:
package-json-file: docs/site/package.json
install: false
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: docs/site/package.json
check-latest: true
# setup-node probes the store from the repository root, not this app.
package-manager-cache: false
- name: Install site dependencies
run: pnpm install --frozen-lockfile
- name: Run package tests
run: pnpm test
- name: Lint site
run: pnpm lint
- name: Typecheck site
run: pnpm exec tsc --noEmit --incremental false
- name: Build site
run: pnpm build
release_gate:
name: Authorize release
if: >-
github.repository == 'stablyai/orca' &&
(github.event_name == 'release' || github.event_name == 'workflow_dispatch')
runs-on: ubuntu-24.04
timeout-minutes: 5
outputs:
deploy: ${{ steps.validate.outputs.deploy }}
commit_sha: ${{ steps.validate.outputs.commit_sha }}
steps:
- name: Validate stable desktop tag
id: validate
env:
EVENT_NAME: ${{ github.event_name }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
INPUT_TAG: ${{ inputs.tag }}
RELEASE_PRERELEASE: ${{ github.event.release.prerelease }}
RELEASE_DRAFT: ${{ github.event.release.draft }}
RELEASE_AUTHOR: ${{ github.event.release.author.login }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
WORKFLOW_REF: ${{ github.ref }}
GH_TOKEN: ${{ github.token }}
shell: bash
working-directory: .
run: |
set -euo pipefail
tag="$INPUT_TAG"
[[ "$EVENT_NAME" == "release" ]] && tag="$RELEASE_TAG"
# Use release-policy’s stable desktop tag shape, excluding mobile-* and RC tags.
stable_tag=false
[[ "$tag" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]] && stable_tag=true
if [[ "$stable_tag" != "true" ]]; then
echo "Release $tag is not a stable desktop release; skipping docs deployment."
echo "deploy=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ "$EVENT_NAME" == "release" ]]; then
authorized_ref=true
authorized_author=false
[[ "$RELEASE_AUTHOR" == "github-actions[bot]" ]] && authorized_author=true
release_state_ok=false
[[ "$RELEASE_PRERELEASE" == "false" && "$RELEASE_DRAFT" == "false" ]] && release_state_ok=true
else
authorized_ref=false
[[ "$WORKFLOW_REF" == "refs/heads/$DEFAULT_BRANCH" ]] && authorized_ref=true
release_json=''
for attempt in 1 2 3; do
if release_json="$(gh api "repos/$GITHUB_REPOSITORY/releases/tags/$tag" 2>/dev/null)"; then
break
fi
if [[ "$attempt" -eq 3 ]]; then
echo "::error::Release metadata for $tag was not available after 3 attempts."
exit 1
fi
sleep "$((attempt * 5))"
done
authorized_author=false
[[ "$(jq -r '.author.login' <<<"$release_json")" == "github-actions[bot]" ]] && authorized_author=true
release_state_ok=false
if [[ "$(jq -r '.tag_name' <<<"$release_json")" == "$tag" &&
"$(jq -r '.prerelease' <<<"$release_json")" == "false" &&
"$(jq -r '.draft' <<<"$release_json")" == "false" ]]; then
release_state_ok=true
fi
fi
# Pin the immutable commit before deployment so force-moving a tag cannot swap authorized source.
tag_ref_json=''
for attempt in 1 2 3; do
if tag_ref_json="$(gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$tag" 2>/dev/null)"; then
break
fi
if [[ "$attempt" -eq 3 ]]; then
echo "::error::Git ref for $tag was not available after 3 attempts."
exit 1
fi
sleep "$((attempt * 5))"
done
tag_object_sha="$(jq -er '.object.sha' <<<"$tag_ref_json")"
tag_object_type="$(jq -er '.object.type' <<<"$tag_ref_json")"
commit_sha="$tag_object_sha"
if [[ "$tag_object_type" == 'tag' ]]; then
commit_sha="$(gh api "repos/$GITHUB_REPOSITORY/git/tags/$tag_object_sha" | jq -er '.object.sha')"
fi
if [[ ! "$commit_sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "::error::Could not resolve $tag to a commit SHA."
exit 1
fi
echo "commit_sha=$commit_sha" >> "$GITHUB_OUTPUT"
# Old stable tags may predate docs; skip before requesting the protected production environment.
docs_source_available=false
for attempt in 1 2 3; do
if gh api "repos/$GITHUB_REPOSITORY/contents/docs/site/package.json?ref=$commit_sha" >/dev/null 2>&1; then
docs_source_available=true
break
fi
[[ "$attempt" -eq 3 ]] || sleep "$((attempt * 5))"
done
if [[ "$docs_source_available" != "true" ]]; then
echo "Release $tag does not contain docs/site; skipping docs deployment."
echo "deploy=false" >> "$GITHUB_OUTPUT"
exit 0
fi
deploy=false
if [[ "$authorized_ref" == "true" && "$authorized_author" == "true" && "$release_state_ok" == "true" ]]; then
deploy=true
else
echo "Release $tag is not an authorized stable desktop release; skipping docs deployment."
fi
echo "deploy=$deploy" >> "$GITHUB_OUTPUT"
production:
name: Production
if: >-
(github.event_name == 'release' || github.event_name == 'workflow_dispatch') &&
needs.release_gate.result == 'success' &&
needs.release_gate.outputs.deploy == 'true'
needs: release_gate
runs-on: ubuntu-24.04
timeout-minutes: 15
environment:
name: docs-production
url: https://orca.dev/docs
env:
VERCEL_TELEMETRY_DISABLED: '1'
steps:
- name: Checkout released tag
uses: actions/checkout@v6
with:
ref: ${{ needs.release_gate.outputs.commit_sha }}
persist-credentials: false
- name: Setup pnpm
uses: pnpm/setup@v2
with:
package-json-file: docs/site/package.json
install: false
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: docs/site/package.json
check-latest: true
package-manager-cache: false
- name: Install site dependencies
run: pnpm install --frozen-lockfile
- name: Verify Vercel credentials
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: |
set -euo pipefail
test -n "${VERCEL_TOKEN:-}" || { echo '::error::VERCEL_TOKEN is not configured for docs-production.'; exit 1; }
test -n "${VERCEL_ORG_ID:-}" || { echo '::error::VERCEL_ORG_ID is not configured for docs-production.'; exit 1; }
test -n "${VERCEL_PROJECT_ID:-}" || { echo '::error::VERCEL_PROJECT_ID is not configured for docs-production.'; exit 1; }
- name: Pull Vercel production settings
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: pnpm exec vercel pull --yes --non-interactive --environment=production
- name: Run package tests
run: pnpm test
- name: Lint site
run: pnpm lint
- name: Typecheck site
run: pnpm exec tsc --noEmit --incremental false
- name: Build production site
run: pnpm exec vercel build --prod --non-interactive
- name: Deploy production site
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: pnpm exec vercel deploy --prebuilt --prod --yes --non-interactive