docs(site): add prod SWA + OIDC deploy + /docs base path#2
Merged
Conversation
Stand up a production Azure Static Web App for the docs site, served at https://auto.azure.com/docs/ through Azure Front Door, and rework the deploy pipeline so it actually runs end-to-end again. What changed: - New prod resources: otto-docs-rg / otto-docs-swa (Free SKU, westus2), fronted by AFD profile otto-portal-afd. The canary SWA stays where it is (otto-docs-canary-swa / lemon-mud-…azurestaticapps.net) and continues to deploy on every push to main. - Workflow rewrite (.github/workflows/docs-site-deploy.yml): - Single build job uploads the artifact; deploy_canary, deploy_prod, and close_pr_preview consume it. - All Azure auth flows through GitHub OIDC + a federated credential on the Otto E2E GitHub Actions SP. No long-lived deployment tokens are stored in this repo; the workflow JIT-fetches the SWA deploy token via 'az staticwebapp secrets list' on every run. - deploy_prod is workflow_dispatch-only and gated by the docs-prod GitHub environment (required reviewers). - PRs from forks build but skip deploy (no secret access by design); same-repo PRs get a free preview environment that's torn down on close. - Preflight check fails fast with a clear error if AZURE_CLIENT_ID / AZURE_TENANT_ID / AZURE_SUBSCRIPTION_ID are missing. - Concurrency groups normalize push and manual canary to the same 'canary' group so they cancel each other; prod runs in its own group and is never auto-cancelled. - Astro site reconfigured for the /docs URL prefix: - base: '/docs' + outDir: './dist/docs' so URLs in HTML and file paths on disk both line up with the AFD route. - scripts/postbuild.mjs hoists staticwebapp.config.json back to dist/ root (where SWA requires it) after astro build. - scripts/remarkBasePrefix.mjs prepends /docs to plain markdown links so content stays portable. - staticwebapp.config.json gets / → /docs/ and /docs → /docs/ 301 redirects; navigationFallback rewrites to /docs/404.html. - Content: replaced otto.azure.com with auto.azure.com in 5 pages now that the new portal domain is live. - INFRA.md fully rewritten with the canary + prod resource map, the OIDC auth flow, and the one-time repo / Azure setup commands needed for disaster recovery. Post-merge follow-ups (done out of band): 1. Repo admin sets AZURE_CLIENT_ID / AZURE_TENANT_ID / AZURE_SUBSCRIPTION_ID secrets and creates the docs-prod environment with required reviewers. 2. Manual workflow_dispatch with target=prod does the first prod deploy. 3. AFD route /docs and /docs/* added on otto-portal-afd pointing to the new prod SWA origin. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AbodeSaafan
approved these changes
May 30, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stands up a production Azure Static Web App for the docs site and reworks the
deploy pipeline so it actually runs end-to-end again. After this PR plus a
small amount of out-of-band setup (see Post-merge follow-ups below), the
docs will be served from
https://auto.azure.com/docs/behind Azure FrontDoor.
Closes the issue where the docs link in the portal pointed at the raw
canary SWA hostname (
https://lemon-mud-…azurestaticapps.net).What changed
New prod infrastructure (already provisioned)
otto-docs-canary-rgotto-docs-rgotto-docs-canary-swaotto-docs-swalemon-mud-0e10bdd1e.7.azurestaticapps.netkind-river-0d9e9ac1e.7.azurestaticapps.nethttps://auto.azure.com/docs/via AFDBoth run in
westus2in the existing Logic Apps subscription. The new RGis tagged
environment=prod project=otto-docs.Workflow rewrite —
/.github/workflows/docs-site-deploy.ymlReplaces a workflow that was failing on every run since May 27
("deployment_token was not provided", because the secret it referenced
didn't exist) with a 4-job pipeline that authenticates via OIDC and
fetches deployment tokens just-in-time:
build— single Astro build, uploaded once as an artifact.deploy_canary— auto on push tomain, on in-repo PRs (previewenvironment), and on manual dispatch with
target=canary(restrictedto
mainto match federated cred coverage).deploy_prod—workflow_dispatchonly withtarget=prod. Gatedby a
docs-prodGitHub environment so prod never deploys without areviewer's click.
close_pr_preview— tears down preview environments when same-repoPRs close.
Fork PRs build but don't deploy (GitHub doesn't pass secrets to fork
workflows — by design). A preflight step fails fast with a clear error
message if the required Azure secrets aren't set.
Astro reconfigured for
/docsbase pathTo serve cleanly behind an AFD route, the site is now built with:
base: '/docs'— Astro emits links and asset URLs under/docs/….outDir: './dist/docs'— file paths on disk match URL paths in HTML.scripts/remarkBasePrefix.mjs) prepends/docsto plain markdown links so content stays portable.scripts/postbuild.mjs) hoistsstaticwebapp.config.jsonback to the dist root (where SWA requiresit) after
astro build.The canary hostname keeps working because
staticwebapp.config.jsonadds
/ → /docs/and/docs → /docs/301 redirects, plus anavigationFallbackrewrite to/docs/404.html.Content
otto.azure.comwithauto.azure.comin 5 doc pages(
introduction.md,setup.md,permissions.md,workflows.md, andinline references). The
otto.azure.comdomain is being decommissioned.INFRA.mdFully rewritten with the canary + prod resource map, the OIDC auth flow,
disaster-recovery
azcommands for re-provisioning everything fromscratch, and the one-time repo configuration that has to happen out of
band.
How auth works now (no stored deploy tokens)
Federated credentials trusted by the SP (already configured):
repo:Azure/Logic-Apps-Automation:ref:refs/heads/mainrepo:Azure/Logic-Apps-Automation:pull_requestrepo:Azure/Logic-Apps-Automation:environment:docs-prodTo rotate a deployment token (or after a suspected leak), run
az staticwebapp secrets reset-api-key …— no workflow or secret changeis needed.
Files changed
.github/workflows/docs-site-deploy.yml— rewrittendocs-site/astro.config.mjs—base,outDir, remark plugindocs-site/package.json— build now runs postbuild script; addedunist-util-visitdocs-site/scripts/postbuild.mjs(new)docs-site/scripts/remarkBasePrefix.mjs(new)docs-site/staticwebapp.config.json— moved out ofpublic/; new redirects + headersdocs-site/INFRA.md— fully rewrittendocs-site/README.md— updated tree + URL refsdocs-site/src/components/Video.astro— fixed a stale JSDoc exampledocs-site/src/content/docs/index.mdx— herolink:frontmatter prefixeddocs-site/src/content/docs/demos/index.mdx—LinkCardusesBASE_URLotto.azure.com→auto.azure.comTesting
npm ci— clean install.npm run check— 0 errors / 0 warnings / 0 hints across 6 Astro files.npm run build— 21 pages built, 5.5 MB output./docs/_astro/*), favicon (/docs/favicon.svg),markdown links, and
LinkCardhrefs all resolve to real files in thedist/tree.actionlint— clean on the new workflow.