From 706f7eb363a54616b17a07a89ccb69c27f603759 Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 8 Jul 2026 14:39:21 -0400 Subject: [PATCH 1/4] chore(docs): deploy docs on release publish --- .github/workflows/main.yml | 5 +++++ README.md | 2 ++ packages/stacks-docs/netlify-ignore.sh | 28 ++++++++++++++++++++++++++ packages/stacks-docs/netlify.toml | 3 +++ 4 files changed, 38 insertions(+) create mode 100644 packages/stacks-docs/netlify-ignore.sh create mode 100644 packages/stacks-docs/netlify.toml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ae0c31b8c4..e7cb41eb61 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -98,6 +98,11 @@ jobs: This is necessary because the PR is updated by github-actions[bot]. This is a technical user which does not trigger actions workflows on push events. See this GH issue for more details: https://github.com/changesets/action/issues/187 + - name: Deploy docs site + if: steps.changesets.outputs.published == 'true' + run: curl --fail --silent --show-error --request POST "$NETLIFY_DOCS_BUILD_HOOK_URL" + env: + NETLIFY_DOCS_BUILD_HOOK_URL: ${{ secrets.NETLIFY_DOCS_BUILD_HOOK_URL }} # cancel the jobs if another workflow is kicked off for the same branch concurrency: diff --git a/README.md b/README.md index 194c571ad8..da1e498d44 100755 --- a/README.md +++ b/README.md @@ -187,6 +187,8 @@ _Despite using changesets to communicate the intent of creating releases in a mo Docs are deployed directly from the current release flow; we no longer merge into a `production` branch to publish stackoverflow.design. Normal contribution PRs target `main`. +When `changesets/action` publishes a new version from `main`, the release workflow triggers the Netlify build hook stored in `NETLIFY_DOCS_BUILD_HOOK_URL`. The docs site also has a Netlify ignore rule so ordinary `main` commits are skipped unless the deployed commit changes one of the released package version files. + ## License Code and documentation copyright 2017-2026 Stack Exchange, Inc and released under the [MIT License](/LICENSE.MD). diff --git a/packages/stacks-docs/netlify-ignore.sh b/packages/stacks-docs/netlify-ignore.sh new file mode 100644 index 0000000000..306be5f99b --- /dev/null +++ b/packages/stacks-docs/netlify-ignore.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Netlify ignores the build when this script exits 0. Exit 1 to build. +repo_root="$(git rev-parse --show-toplevel)" +cd "$repo_root" + +head_ref="${COMMIT_REF:-HEAD}" +base_ref="$head_ref^" + +if ! git rev-parse --verify "$base_ref" >/dev/null 2>&1; then + echo "Building docs deploy: no previous commit is available." + exit 1 +fi + +version_files=( + "packages/stacks-classic/package.json" + "packages/stacks-svelte/package.json" + "packages/stacks-utils/package.json" +) + +if git diff --quiet "$base_ref" "$head_ref" -- "${version_files[@]}"; then + echo "Skipping docs deploy: no package versions changed." + exit 0 +fi + +echo "Building docs deploy: package versions changed." +exit 1 diff --git a/packages/stacks-docs/netlify.toml b/packages/stacks-docs/netlify.toml new file mode 100644 index 0000000000..9bfbf66a0a --- /dev/null +++ b/packages/stacks-docs/netlify.toml @@ -0,0 +1,3 @@ +[build] + # Netlify treats exit code 0 as "ignore this build" and non-zero as "build". + ignore = "bash netlify-ignore.sh" From 436c6131e269bc9e724604f300ccfceb270fc179 Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 8 Jul 2026 15:26:57 -0400 Subject: [PATCH 2/4] chore(docs): add manual docs deploy --- .github/workflows/main.yml | 18 +++++++++++++++++- README.md | 2 +- packages/stacks-docs/netlify-ignore.sh | 5 +++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e7cb41eb61..0196187e86 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,10 +5,12 @@ on: branches: [main] pull_request: branches: [main] + workflow_dispatch: jobs: build-and-test: name: ${{ matrix.command_description }} + if: github.event_name != 'workflow_dispatch' uses: ./.github/workflows/test.yml strategy: fail-fast: false @@ -55,7 +57,7 @@ jobs: release: name: "Release (main)" - if: github.ref == 'refs/heads/main' + if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: [build-and-test] runs-on: ubuntu-latest env: @@ -104,6 +106,20 @@ jobs: env: NETLIFY_DOCS_BUILD_HOOK_URL: ${{ secrets.NETLIFY_DOCS_BUILD_HOOK_URL }} + deploy-docs: + name: "Deploy docs (manual)" + if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - name: Deploy docs site + run: | + curl --fail --silent --show-error \ + --request POST \ + --data '{"forceDocsDeploy":true,"source":"workflow_dispatch"}' \ + "$NETLIFY_DOCS_BUILD_HOOK_URL?trigger_branch=main&trigger_title=Manual+docs+deploy" + env: + NETLIFY_DOCS_BUILD_HOOK_URL: ${{ secrets.NETLIFY_DOCS_BUILD_HOOK_URL }} + # cancel the jobs if another workflow is kicked off for the same branch concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/README.md b/README.md index da1e498d44..692d01339d 100755 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ _Despite using changesets to communicate the intent of creating releases in a mo Docs are deployed directly from the current release flow; we no longer merge into a `production` branch to publish stackoverflow.design. Normal contribution PRs target `main`. -When `changesets/action` publishes a new version from `main`, the release workflow triggers the Netlify build hook stored in `NETLIFY_DOCS_BUILD_HOOK_URL`. The docs site also has a Netlify ignore rule so ordinary `main` commits are skipped unless the deployed commit changes one of the released package version files. +When `changesets/action` publishes a new version from `main`, the release workflow triggers the Netlify build hook stored in `NETLIFY_DOCS_BUILD_HOOK_URL`. The docs site also has a Netlify ignore rule so ordinary `main` commits are skipped unless the deployed commit changes one of the released package version files. To deploy the latest `main` docs without publishing packages, manually run the CI workflow from the `main` branch. ## License Code and documentation copyright 2017-2026 Stack Exchange, Inc and released under the [MIT License](/LICENSE.MD). diff --git a/packages/stacks-docs/netlify-ignore.sh b/packages/stacks-docs/netlify-ignore.sh index 306be5f99b..e60e8ca0cb 100644 --- a/packages/stacks-docs/netlify-ignore.sh +++ b/packages/stacks-docs/netlify-ignore.sh @@ -8,6 +8,11 @@ cd "$repo_root" head_ref="${COMMIT_REF:-HEAD}" base_ref="$head_ref^" +if [[ "${INCOMING_HOOK_BODY:-}" == *"forceDocsDeploy"* ]]; then + echo "Building docs deploy: manual deploy requested." + exit 1 +fi + if ! git rev-parse --verify "$base_ref" >/dev/null 2>&1; then echo "Building docs deploy: no previous commit is available." exit 1 From 5f6e13d283abd3b7a6ee1c3699b064d45ea55aac Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 8 Jul 2026 15:35:26 -0400 Subject: [PATCH 3/4] chore(docs): preserve deploy previews --- .github/workflows/deploy-docs.yml | 23 +++++++++++++++++++++++ .github/workflows/main.yml | 15 +-------------- README.md | 2 +- packages/stacks-docs/netlify-ignore.sh | 5 +++++ 4 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/deploy-docs.yml diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000000..e1da7aff00 --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,23 @@ +name: Deploy docs + +on: + workflow_dispatch: + +jobs: + deploy-docs: + name: "Deploy docs (manual)" + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - name: Deploy docs site + run: | + curl --fail --silent --show-error \ + --request POST \ + --data '{"forceDocsDeploy":true,"source":"workflow_dispatch"}' \ + "$NETLIFY_DOCS_BUILD_HOOK_URL?trigger_branch=main&trigger_title=Manual+docs+deploy" + env: + NETLIFY_DOCS_BUILD_HOOK_URL: ${{ secrets.NETLIFY_DOCS_BUILD_HOOK_URL }} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0196187e86..1a6367c850 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,12 +5,10 @@ on: branches: [main] pull_request: branches: [main] - workflow_dispatch: jobs: build-and-test: name: ${{ matrix.command_description }} - if: github.event_name != 'workflow_dispatch' uses: ./.github/workflows/test.yml strategy: fail-fast: false @@ -102,21 +100,10 @@ jobs: See this GH issue for more details: https://github.com/changesets/action/issues/187 - name: Deploy docs site if: steps.changesets.outputs.published == 'true' - run: curl --fail --silent --show-error --request POST "$NETLIFY_DOCS_BUILD_HOOK_URL" - env: - NETLIFY_DOCS_BUILD_HOOK_URL: ${{ secrets.NETLIFY_DOCS_BUILD_HOOK_URL }} - - deploy-docs: - name: "Deploy docs (manual)" - if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' - runs-on: ubuntu-latest - steps: - - name: Deploy docs site run: | curl --fail --silent --show-error \ --request POST \ - --data '{"forceDocsDeploy":true,"source":"workflow_dispatch"}' \ - "$NETLIFY_DOCS_BUILD_HOOK_URL?trigger_branch=main&trigger_title=Manual+docs+deploy" + "$NETLIFY_DOCS_BUILD_HOOK_URL?trigger_branch=main&trigger_title=Release+docs+deploy" env: NETLIFY_DOCS_BUILD_HOOK_URL: ${{ secrets.NETLIFY_DOCS_BUILD_HOOK_URL }} diff --git a/README.md b/README.md index 692d01339d..f0e4321aec 100755 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ _Despite using changesets to communicate the intent of creating releases in a mo Docs are deployed directly from the current release flow; we no longer merge into a `production` branch to publish stackoverflow.design. Normal contribution PRs target `main`. -When `changesets/action` publishes a new version from `main`, the release workflow triggers the Netlify build hook stored in `NETLIFY_DOCS_BUILD_HOOK_URL`. The docs site also has a Netlify ignore rule so ordinary `main` commits are skipped unless the deployed commit changes one of the released package version files. To deploy the latest `main` docs without publishing packages, manually run the CI workflow from the `main` branch. +When `changesets/action` publishes a new version from `main`, the release workflow triggers the Netlify build hook stored in `NETLIFY_DOCS_BUILD_HOOK_URL`. The docs site also has a Netlify ignore rule so ordinary `main` commits are skipped unless the deployed commit changes one of the released package version files. To deploy the latest `main` docs without publishing packages, manually run the Deploy docs workflow from the `main` branch. ## License Code and documentation copyright 2017-2026 Stack Exchange, Inc and released under the [MIT License](/LICENSE.MD). diff --git a/packages/stacks-docs/netlify-ignore.sh b/packages/stacks-docs/netlify-ignore.sh index e60e8ca0cb..3ac432c5a8 100644 --- a/packages/stacks-docs/netlify-ignore.sh +++ b/packages/stacks-docs/netlify-ignore.sh @@ -13,6 +13,11 @@ if [[ "${INCOMING_HOOK_BODY:-}" == *"forceDocsDeploy"* ]]; then exit 1 fi +if [[ "${CONTEXT:-}" == "deploy-preview" || "${CONTEXT:-}" == "branch-deploy" ]]; then + echo "Building docs deploy: ${CONTEXT} context." + exit 1 +fi + if ! git rev-parse --verify "$base_ref" >/dev/null 2>&1; then echo "Building docs deploy: no previous commit is available." exit 1 From ee6ce82fa1aec44355ef18df70075bdbb923f59a Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 8 Jul 2026 15:45:58 -0400 Subject: [PATCH 4/4] chore(docs): restrict manual deploy permissions --- .github/workflows/deploy-docs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index e1da7aff00..5c3f027081 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -3,6 +3,8 @@ name: Deploy docs on: workflow_dispatch: +permissions: {} + jobs: deploy-docs: name: "Deploy docs (manual)"