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
27 changes: 22 additions & 5 deletions .github/workflows/deploy-site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ on:
- '.github/workflows/deploy-site.yml'
workflow_dispatch:

# Allow GITHUB_TOKEN to deploy to Pages and verify the deployment origin.
permissions:
contents: read
pages: write
id-token: write

# One deploy at a time; let an in-progress run finish.
concurrency:
Expand All @@ -29,11 +26,31 @@ jobs:
uses: withastro/action@v6
with:
path: site
node-version: 22
node-version: 24

deploy:
check-pages:
needs: build
runs-on: ubuntu-latest
outputs:
deploy: ${{ steps.pages.outputs.deploy }}
steps:
- uses: actions/checkout@v6
- name: Test Pages deployment decision
run: bash scripts/test-pages-deploy.sh
- name: Check repository Pages configuration
id: pages
env:
GH_TOKEN: ${{ github.token }}
run: bash scripts/check-pages-deploy.sh

deploy:
needs: [build, check-pages]
if: ${{ needs['check-pages'].outputs.deploy == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
Expand Down
31 changes: 31 additions & 0 deletions scripts/check-pages-deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -euo pipefail

# The upstream repository's existing Pages deployment remains unconditional.
if [[ "$GITHUB_REPOSITORY" == 'colbymchenry/codegraph' ]]; then
printf 'deploy=true\n' >> "$GITHUB_OUTPUT"
echo 'Official repository: deploy the built site.'
exit 0
fi

# A fork can run the full site build without enabling Pages. This GET is the
# only repository query; a failed or malformed response must fail the job.
if ! has_pages="$(gh api "repos/$GITHUB_REPOSITORY" --jq '.has_pages')"; then
echo "Could not read Pages configuration for $GITHUB_REPOSITORY." >&2
exit 1
fi

case "$has_pages" in
true)
printf 'deploy=true\n' >> "$GITHUB_OUTPUT"
echo "Pages is configured for $GITHUB_REPOSITORY; deploy the built site."
;;
false)
printf 'deploy=false\n' >> "$GITHUB_OUTPUT"
echo "Pages is not configured for $GITHUB_REPOSITORY; the site build is complete and deployment is skipped."
;;
*)
echo "Unexpected Pages configuration response for $GITHUB_REPOSITORY: $has_pages" >&2
exit 1
;;
esac
40 changes: 40 additions & 0 deletions scripts/test-pages-deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -euo pipefail

test_dir="$(mktemp -d)"
trap 'rm -rf "$test_dir"' EXIT
cat > "$test_dir/gh" <<'GH'
#!/usr/bin/env bash
[[ "$#" -eq 4 && "$1" == api && "$2" == "repos/$GITHUB_REPOSITORY" && "$3" == --jq && "$4" == .has_pages ]] || exit 90
case "$GH_TEST_RESULT" in
true|false) printf '%s\n' "$GH_TEST_RESULT" ;;
error) exit 42 ;;
*) printf 'unexpected\n' ;;
esac
GH
chmod +x "$test_dir/gh"

check_case() {
local repository="$1" response="$2" expected="$3"
: > "$test_dir/output"
GITHUB_REPOSITORY="$repository" GITHUB_OUTPUT="$test_dir/output" \
GH_TEST_RESULT="$response" PATH="$test_dir:$PATH" \
bash scripts/check-pages-deploy.sh > "$test_dir/stdout" 2> "$test_dir/stderr"
[[ "$(cat "$test_dir/output")" == "deploy=$expected" ]]
}

check_case colbymchenry/codegraph error true
check_case partme-ai/codegraph true true
check_case partme-ai/codegraph false false
grep -q 'not configured' "$test_dir/stdout"

: > "$test_dir/output"
if GITHUB_REPOSITORY=partme-ai/codegraph GITHUB_OUTPUT="$test_dir/output" \
GH_TEST_RESULT=error PATH="$test_dir:$PATH" \
bash scripts/check-pages-deploy.sh > "$test_dir/stdout" 2> "$test_dir/stderr"; then
echo 'Pages API failure must fail the workflow.' >&2
exit 1
fi
[[ ! -s "$test_dir/output" ]]
grep -q 'Could not read Pages configuration' "$test_dir/stderr"
echo 'Pages deployment decision: official, enabled fork, unconfigured fork and API error passed.'
Loading
Loading