De-technicalize Tasks and Task Credits core concept pages #221
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docs | |
| on: | |
| pull_request: | |
| paths: | |
| - "docs/**" | |
| - ".github/workflows/docs.yml" | |
| push: | |
| branches: [main] | |
| paths: | |
| - "docs/**" | |
| - ".github/workflows/docs.yml" | |
| workflow_dispatch: {} | |
| concurrency: | |
| group: docs-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| packages: write | |
| pull-requests: read | |
| env: | |
| DOCS_SITE_URL: https://docs.gobii.ai | |
| DOCS_IMAGE: ghcr.io/gobii-ai/gobii-docs | |
| jobs: | |
| preview_preflight: | |
| name: Resolve Docs Preview Inputs | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| outputs: | |
| docs_changed: ${{ steps.resolve.outputs.docs_changed }} | |
| head_sha: ${{ steps.resolve.outputs.head_sha }} | |
| short_sha: ${{ steps.resolve.outputs.short_sha }} | |
| preview_url: ${{ steps.resolve.outputs.preview_url }} | |
| steps: | |
| - name: Resolve PR docs changes | |
| id: resolve | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const pr = context.payload.pull_request; | |
| if (!pr) { | |
| throw new Error('pull_request payload missing.'); | |
| } | |
| const files = await github.paginate(github.rest.pulls.listFiles, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: pr.number, | |
| per_page: 100, | |
| }); | |
| const docsChanged = files.some((file) => file.filename.startsWith('docs/')); | |
| const headSha = pr.head.sha; | |
| core.setOutput('docs_changed', String(docsChanged)); | |
| core.setOutput('head_sha', headSha); | |
| core.setOutput('short_sha', headSha.substring(0, 7)); | |
| core.setOutput('preview_url', `https://docs-pr-${pr.number}.ship.gobii.ai`); | |
| build: | |
| name: Build Docs | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Set up Node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "22" | |
| cache: npm | |
| cache-dependency-path: docs/package-lock.json | |
| - name: Install dependencies | |
| working-directory: docs | |
| run: npm ci | |
| - name: Verify analytics secret | |
| if: github.event_name != 'pull_request' | |
| env: | |
| DOCS_GTAG_TRACKING_ID: ${{ secrets.DOCS_GTAG_TRACKING_ID }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${DOCS_GTAG_TRACKING_ID:-}" ]; then | |
| echo "DOCS_GTAG_TRACKING_ID must be configured on gobii-ai/gobii-platform for production docs builds." >&2 | |
| exit 1 | |
| fi | |
| - name: Build static docs | |
| working-directory: docs | |
| env: | |
| DOCS_GTAG_TRACKING_ID: ${{ secrets.DOCS_GTAG_TRACKING_ID }} | |
| run: npm run build | |
| - name: Verify analytics tag when configured | |
| working-directory: docs | |
| env: | |
| DOCS_GTAG_TRACKING_ID: ${{ secrets.DOCS_GTAG_TRACKING_ID }} | |
| run: | | |
| set -euo pipefail | |
| if [ -n "${DOCS_GTAG_TRACKING_ID:-}" ]; then | |
| grep -q 'googletagmanager.com/gtag/js?id=' build/index.html | |
| fi | |
| - name: Verify required routes | |
| working-directory: docs | |
| run: | | |
| set -euo pipefail | |
| required=( | |
| build/index.html | |
| build/getting-started/introduction.html | |
| build/developers/developer-basics.html | |
| build/api-reference/gobii-api.html | |
| build/api-reference/list-persistent-agents.html | |
| build/api-reference/agents-api/get-agents.html | |
| build/api-reference/agents-api/get-agents.md | |
| build/GobiiAPI.yaml | |
| build/openapi/GobiiAPI.yaml | |
| build/legacy-redirects.conf | |
| build/api-reference/openapi.json | |
| build/llms.txt | |
| build/llms-full.txt | |
| build/pagefind/pagefind-ui.js | |
| ) | |
| for file in "${required[@]}"; do | |
| test -s "$file" | |
| done | |
| - name: Verify nginx routing | |
| working-directory: docs | |
| env: | |
| DOCS_GTAG_TRACKING_ID: ${{ secrets.DOCS_GTAG_TRACKING_ID }} | |
| run: | | |
| set -euo pipefail | |
| image="gobii-docs-ci:${GITHUB_SHA}" | |
| container="gobii-docs-ci-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" | |
| docker build \ | |
| --build-arg DOCS_SITE_URL="${DOCS_SITE_URL}" \ | |
| --build-arg DOCS_GTAG_TRACKING_ID="${DOCS_GTAG_TRACKING_ID}" \ | |
| -t "$image" . | |
| docker run -d --rm --name "$container" -p 8080:8080 "$image" | |
| trap 'docker rm -f "$container" >/dev/null 2>&1 || true' EXIT | |
| ready=0 | |
| for _ in {1..20}; do | |
| if curl -fsS http://127.0.0.1:8080/healthz >/dev/null 2>&1; then | |
| ready=1 | |
| break | |
| fi | |
| sleep 1 | |
| done | |
| test "$ready" = "1" | |
| code_for() { | |
| curl -sS -o /dev/null -w '%{http_code}' "http://127.0.0.1:8080$1" | |
| } | |
| redirect_for() { | |
| curl -sS -o /dev/null -w '%{http_code} %{redirect_url}' "http://127.0.0.1:8080$1" | |
| } | |
| test "$(code_for /)" = "200" | |
| test "$(code_for /healthz)" = "200" | |
| if [ -n "${DOCS_GTAG_TRACKING_ID:-}" ]; then | |
| curl -fsS http://127.0.0.1:8080/ | grep -q 'googletagmanager.com/gtag/js?id=' | |
| fi | |
| test "$(code_for /api-reference/gobii-api)" = "200" | |
| test "$(code_for /api-reference/list-persistent-agents)" = "200" | |
| test "$(redirect_for /index.html)" = "301 http://127.0.0.1:8080/" | |
| test "$(redirect_for /api-reference)" = "301 http://127.0.0.1:8080/api-reference/gobii-api" | |
| test "$(redirect_for /api-reference/agents-api/get-agents)" = "301 http://127.0.0.1:8080/api-reference/list-persistent-agents" | |
| test "$(redirect_for '/api-reference/agents-api/get-agents?utm_source=x')" = "301 http://127.0.0.1:8080/api-reference/list-persistent-agents?utm_source=x" | |
| test "$(redirect_for /api-reference/agents-api/get-agents.html)" = "301 http://127.0.0.1:8080/api-reference/list-persistent-agents" | |
| test "$(redirect_for /getting-started/introduction)" = "301 http://127.0.0.1:8080/" | |
| test "$(redirect_for /getting-started/introduction.html)" = "301 http://127.0.0.1:8080/" | |
| test "$(redirect_for /getting-started/introduction/)" = "301 http://127.0.0.1:8080/" | |
| test "$(redirect_for /core-concepts)" = "301 http://127.0.0.1:8080/start-here/core-concepts" | |
| test "$(redirect_for /core-concepts.html)" = "301 http://127.0.0.1:8080/start-here/core-concepts" | |
| test "$(redirect_for /core-concepts/)" = "301 http://127.0.0.1:8080/start-here/core-concepts" | |
| test "$(redirect_for /console-guides)" = "301 http://127.0.0.1:8080/using-gobii" | |
| test "$(redirect_for /console-guides.html)" = "301 http://127.0.0.1:8080/using-gobii" | |
| test "$(redirect_for /console-guides/)" = "301 http://127.0.0.1:8080/using-gobii" | |
| test "$(redirect_for /console-guides/live-chat-guide)" = "301 http://127.0.0.1:8080/using-gobii/chat-and-timeline" | |
| test "$(redirect_for /console-guides/live-chat-guide.html)" = "301 http://127.0.0.1:8080/using-gobii/chat-and-timeline" | |
| test "$(redirect_for /console-guides/live-chat-guide/)" = "301 http://127.0.0.1:8080/using-gobii/chat-and-timeline" | |
| test "$(redirect_for /console-guides/meta-gobii)" = "301 http://127.0.0.1:8080/using-gobii/meta-gobii" | |
| test "$(redirect_for /console-guides/meta-gobii.html)" = "301 http://127.0.0.1:8080/using-gobii/meta-gobii" | |
| test "$(redirect_for /console-guides/meta-gobii/)" = "301 http://127.0.0.1:8080/using-gobii/meta-gobii" | |
| test "$(code_for /using-gobii/meta-gobii)" = "200" | |
| test "$(code_for /definitely-not-a-real-docs-url)" = "404" | |
| test "$(redirect_for /definitely-not-a-real-docs-url/)" = "301 http://127.0.0.1:8080/definitely-not-a-real-docs-url" | |
| test "$(code_for /404)" = "404" | |
| test "$(code_for /404.html)" = "404" | |
| header_for() { | |
| local path="$1" | |
| local header="$2" | |
| curl -sSI "http://127.0.0.1:8080${path}" \ | |
| | awk -v header="${header}" 'BEGIN { IGNORECASE = 1 } index($0, header ":") == 1 { sub("\r$", ""); sub("^[^:]+: *", ""); print; exit }' | |
| } | |
| asset_js="$(node - <<'NODE' | |
| (async () => { | |
| const html = await (await fetch('http://127.0.0.1:8080/')).text(); | |
| const match = html.match(/\/assets\/js\/[^"]+\.js/); | |
| if (!match) process.exit(1); | |
| console.log(match[0]); | |
| })(); | |
| NODE | |
| )" | |
| pagefind_fragment="/$(find build/pagefind/fragment -name '*.pf_fragment' -print -quit | sed 's#^build/##')" | |
| test "$(header_for /healthz Cache-Control)" = "no-store" | |
| test "$(header_for / Cache-Control)" = "public, max-age=0, must-revalidate" | |
| test "$(header_for / CDN-Cache-Control)" = "public, max-age=300, stale-while-revalidate=86400" | |
| test "$(header_for / Cloudflare-CDN-Cache-Control)" = "public, max-age=300, stale-while-revalidate=86400" | |
| test "$(header_for "$asset_js" Cache-Control)" = "public, max-age=31536000, immutable" | |
| test "$(header_for /assets/js/not-real.js Cache-Control)" = "" | |
| test "$(header_for /pagefind/pagefind-ui.js Cache-Control)" = "public, max-age=300, must-revalidate" | |
| test "$(header_for "$pagefind_fragment" Cache-Control)" = "public, max-age=31536000, immutable" | |
| test "$(header_for /api-reference/openapi.json Cloudflare-CDN-Cache-Control)" = "public, max-age=300, stale-while-revalidate=86400" | |
| test "$(header_for /api-reference/openapi.json X-Robots-Tag)" = "noindex" | |
| test "$(header_for /developers.md Cache-Control)" = "public, max-age=300, must-revalidate" | |
| test "$(header_for /developers.md X-Robots-Tag)" = "noindex" | |
| test "$(header_for /llms.txt X-Robots-Tag)" = "noindex" | |
| test "$(header_for /llms-full.txt X-Robots-Tag)" = "noindex" | |
| test "$(header_for /GobiiAPI.yaml X-Robots-Tag)" = "noindex" | |
| test "$(header_for /openapi/GobiiAPI.yaml X-Robots-Tag)" = "noindex" | |
| test "$(header_for / X-Robots-Tag)" = "" | |
| test "$(header_for /api-reference/list-persistent-agents X-Robots-Tag)" = "" | |
| test "$(header_for /api-reference/agents-api/get-agents Cache-Control)" = "public, max-age=300" | |
| publish: | |
| name: Publish Docs Image | |
| runs-on: ubuntu-latest | |
| needs: [build] | |
| if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' | |
| outputs: | |
| short_sha: ${{ steps.meta.outputs.short_sha }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Resolve image metadata | |
| id: meta | |
| run: | | |
| short_sha="${GITHUB_SHA::7}" | |
| echo "short_sha=${short_sha}" >> "$GITHUB_OUTPUT" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push docs image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: docs | |
| file: docs/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ env.DOCS_IMAGE }}:sha-${{ github.sha }} | |
| ${{ env.DOCS_IMAGE }}:sha-${{ steps.meta.outputs.short_sha }} | |
| ${{ env.DOCS_IMAGE }}:staging | |
| labels: | | |
| org.opencontainers.image.revision=${{ github.sha }} | |
| build-args: | | |
| DOCS_SITE_URL=${{ env.DOCS_SITE_URL }} | |
| DOCS_GTAG_TRACKING_ID=${{ secrets.DOCS_GTAG_TRACKING_ID }} | |
| cache-from: type=gha,scope=gobii-docs | |
| cache-to: type=gha,mode=max,scope=gobii-docs | |
| platforms: linux/amd64 | |
| provenance: false | |
| sbom: false | |
| publish_preview: | |
| name: Publish Docs Preview Image | |
| runs-on: ubuntu-latest | |
| needs: [build, preview_preflight] | |
| if: > | |
| github.event_name == 'pull_request' && | |
| needs.preview_preflight.outputs.docs_changed == 'true' && | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| outputs: | |
| image: ${{ steps.meta.outputs.image }} | |
| steps: | |
| - name: Checkout PR head | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ needs.preview_preflight.outputs.head_sha }} | |
| - name: Resolve image metadata | |
| id: meta | |
| env: | |
| HEAD_SHA: ${{ needs.preview_preflight.outputs.head_sha }} | |
| run: | | |
| set -euo pipefail | |
| echo "image=${DOCS_IMAGE}:sha-${HEAD_SHA}" >> "$GITHUB_OUTPUT" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push docs preview image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: docs | |
| file: docs/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ env.DOCS_IMAGE }}:sha-${{ needs.preview_preflight.outputs.head_sha }} | |
| ${{ env.DOCS_IMAGE }}:pr-${{ github.event.pull_request.number }} | |
| labels: | | |
| org.opencontainers.image.revision=${{ needs.preview_preflight.outputs.head_sha }} | |
| build-args: | | |
| DOCS_SITE_URL=${{ needs.preview_preflight.outputs.preview_url }} | |
| cache-from: type=gha,scope=gobii-docs | |
| cache-to: type=gha,mode=max,scope=gobii-docs | |
| platforms: linux/amd64 | |
| provenance: false | |
| sbom: false | |
| deploy_preview: | |
| name: Dispatch Docs Preview Deployment | |
| runs-on: ubuntu-latest | |
| needs: [preview_preflight, publish_preview] | |
| if: > | |
| github.event_name == 'pull_request' && | |
| needs.preview_preflight.outputs.docs_changed == 'true' && | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| steps: | |
| - name: Generate GitHub App token | |
| id: app-token | |
| uses: actions/create-github-app-token@v3 | |
| with: | |
| app-id: ${{ secrets.GH_APP_ID }} | |
| private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
| owner: gobii-ai | |
| repositories: gobii | |
| - name: Notify infra repo | |
| uses: peter-evans/repository-dispatch@v4 | |
| with: | |
| token: ${{ steps.app-token.outputs.token }} | |
| repository: gobii-ai/gobii | |
| event-type: docs-preview-ready | |
| client-payload: | | |
| { | |
| "owner": "${{ github.repository_owner }}", | |
| "repo": "${{ github.event.repository.name }}", | |
| "pr_number": ${{ github.event.pull_request.number }}, | |
| "head_sha": "${{ needs.preview_preflight.outputs.head_sha }}", | |
| "image": "${{ needs.publish_preview.outputs.image }}", | |
| "html_url": "${{ github.event.pull_request.html_url }}", | |
| "trigger_run_id": ${{ github.run_id }}, | |
| "trigger_run_attempt": ${{ github.run_attempt }}, | |
| "actor": "${{ github.actor }}" | |
| } | |
| deploy: | |
| name: Dispatch Docs Staging Deployment | |
| runs-on: ubuntu-latest | |
| needs: [publish] | |
| if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' | |
| steps: | |
| - name: Generate GitHub App token | |
| id: app-token | |
| uses: actions/create-github-app-token@v3 | |
| with: | |
| app-id: ${{ secrets.GH_APP_ID }} | |
| private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
| owner: gobii-ai | |
| repositories: gobii | |
| - name: Notify infra repo | |
| uses: peter-evans/repository-dispatch@v4 | |
| with: | |
| token: ${{ steps.app-token.outputs.token }} | |
| repository: gobii-ai/gobii | |
| event-type: docs-staging-ready | |
| client-payload: | | |
| { | |
| "owner": "${{ github.repository_owner }}", | |
| "repo": "${{ github.event.repository.name }}", | |
| "ref": "${{ github.ref }}", | |
| "head_sha": "${{ github.sha }}", | |
| "short_sha": "${{ needs.publish.outputs.short_sha }}", | |
| "image": "${{ env.DOCS_IMAGE }}:sha-${{ github.sha }}", | |
| "trigger_run_id": ${{ github.run_id }}, | |
| "trigger_run_attempt": ${{ github.run_attempt }}, | |
| "actor": "${{ github.actor }}" | |
| } |