Skip to content
Open
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
89 changes: 50 additions & 39 deletions .github/workflows/hugo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ on:

concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || (inputs.operation == 'staging-next' && 'asf-staging-oink' || 'asf-site') }}
# A newer commit supersedes previous work for the same PR or publish target.
cancel-in-progress: true

env:
Expand All @@ -51,6 +52,7 @@ jobs:
artifact_prefix: ${{ steps.plan.outputs.artifact_prefix }}
publish_branch: ${{ steps.plan.outputs.publish_branch }}
latest_sha: ${{ steps.plan.outputs.latest_sha }}
source_sha: ${{ steps.plan.outputs.source_sha }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
Expand Down Expand Up @@ -103,7 +105,6 @@ jobs:
latest_sha="$EVENT_SHA"

if [[ "$EVENT_NAME" == workflow_dispatch ]]; then
test "$GITHUB_REF" = refs/heads/master
candidate="$CANDIDATE_BRANCH"
test -n "$candidate"
[[ "$candidate" =~ ^[A-Za-z0-9][A-Za-z0-9._/-]*$ ]]
Expand All @@ -119,6 +120,9 @@ jobs:

case "$OPERATION" in
staging-next)
# Dispatches must load this privileged workflow from master;
# the candidate is data resolved to an immutable commit below.
test "$GITHUB_REF" = "refs/heads/master"
test "$CONFIRMATION" = "publish asf-staging-oink"
site_origin="$STAGING_ORIGIN"
artifact_prefix="staging"
Expand All @@ -131,6 +135,7 @@ jobs:
fi
;;
production-history-refresh)
test "$GITHUB_REF" = refs/heads/master
test "$CONFIRMATION" = "publish asf-site"
test "$candidate" = "$latest_ref"
test "$SCOPE" = full
Expand All @@ -152,11 +157,13 @@ jobs:
echo "artifact_prefix=$artifact_prefix"
echo "publish_branch=$publish_branch"
echo "latest_sha=$latest_sha"
echo "source_sha=$latest_sha"
} >> "$GITHUB_OUTPUT"

- name: Validate source and version tooling
run: |
bash dist/validate-links.sh
go mod download
PYTHONDONTWRITEBYTECODE=1 \
python3 -m unittest discover -s scripts -p 'test_*.py' -v
- name: Resolve immutable version matrix
Expand All @@ -172,10 +179,12 @@ jobs:
- name: Upload resolved version manifest
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: resolved-versions-${{ github.run_id }}-${{ github.run_attempt }}
# Keep dependency artifact names stable across selective job reruns.
name: resolved-versions-${{ github.run_id }}
path: resolved-versions.json
retention-days: 7
if-no-files-found: error
overwrite: true

build:
needs: prepare
Expand All @@ -193,7 +202,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ needs.prepare.outputs.source_sha }}
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
Expand Down Expand Up @@ -223,11 +232,10 @@ jobs:
restore-keys: ${{ runner.os }}-hugo-${{ env.HUGO_VERSION }}-${{ matrix.version.id }}-
- name: Verify pinned OINK module
run: |
go mod verify
test "$(go list -m -f '{{ .Path }}')" = "github.com/apache/hugegraph-doc"
test "$(go list -m all | wc -l)" -eq 2
test "$(go list -m -f '{{ .Path }}@{{ .Version }}' github.com/pgsty/oink)" = "github.com/pgsty/oink@v1.0.0"
test -z "$(go list -m -f '{{ with .Replace }}{{ .Path }}@{{ .Version }}{{ end }}' github.com/pgsty/oink)"
test -z "$(go list -m -f '{{ with .Replace }}{{ .Path }}{{ end }}' github.com/pgsty/oink)"
python3 scripts/update_oink.py --check-baseline
- name: Build isolated version artifact
env:
OINK_PYTHON: python3
Expand All @@ -245,32 +253,36 @@ jobs:
- name: Upload isolated version artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: ${{ needs.prepare.outputs.artifact_prefix }}-${{ matrix.version.id }}-${{ github.run_id }}-${{ github.run_attempt }}
name: ${{ needs.prepare.outputs.artifact_prefix }}-${{ matrix.version.id }}-${{ github.run_id }}
path: ${{ runner.temp }}/version-public
include-hidden-files: true
retention-days: 1
if-no-files-found: error
overwrite: true

# Assembly and browser checks are serial; reuse one runner and its local output.
aggregate:
needs: [prepare, build]
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 35
permissions: { contents: read }
env:
HUGO_CACHEDIR: /tmp/hugo-cache-${{ github.run_id }}-${{ github.run_attempt }}-aggregate
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ needs.prepare.outputs.source_sha }}
persist-credentials: false
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.13"
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: resolved-versions-${{ github.run_id }}-${{ github.run_attempt }}
name: resolved-versions-${{ github.run_id }}
path: resolved
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
pattern: ${{ needs.prepare.outputs.artifact_prefix }}-*-${{ github.run_id }}-${{ github.run_attempt }}
pattern: ${{ needs.prepare.outputs.artifact_prefix }}-*-${{ github.run_id }}
path: version-artifacts
- name: Assemble publishable site
env:
Expand All @@ -285,32 +297,25 @@ jobs:
fi
python3 scripts/versioning.py aggregate \
--artifacts version-artifacts --artifact-prefix "$PREFIX-" \
--artifact-suffix="-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" \
--artifact-suffix="-${GITHUB_RUN_ID}" \
--resolved-manifest resolved/resolved-versions.json \
--site-origin "$SITE_ORIGIN" --historical-origin "$HISTORICAL_ORIGIN" \
--select "$SELECTION" \
--output "${RUNNER_TEMP}/public-site" "${extra[@]}"
- name: Verify rendered download contracts
env:
DOWNLOAD_PUBLIC_DIR: ${{ runner.temp }}/public-site
run: python3 -m unittest scripts.test_download_data.DownloadDataTest.test_rendered_download_pages_have_verified_rows -v
- name: Upload publishable aggregate
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: hugegraph-site-${{ needs.prepare.outputs.artifact_prefix }}-${{ github.run_id }}-${{ github.run_attempt }}
name: hugegraph-site-${{ needs.prepare.outputs.artifact_prefix }}-${{ github.run_id }}
path: ${{ runner.temp }}/public-site
include-hidden-files: true
retention-days: ${{ github.event_name == 'pull_request' && 1 || 7 }}
if-no-files-found: error
overwrite: true

e2e:
needs: [prepare, aggregate]
runs-on: ubuntu-latest
timeout-minutes: 20
permissions: { contents: read }
env:
HUGO_CACHEDIR: /tmp/hugo-cache-${{ github.run_id }}-${{ github.run_attempt }}-e2e
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: "24"
Expand All @@ -325,10 +330,6 @@ jobs:
with:
hugo-version: ${{ env.HUGO_VERSION }}
extended: true
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: hugegraph-site-${{ needs.prepare.outputs.artifact_prefix }}-${{ github.run_id }}-${{ github.run_attempt }}
path: public-site
- name: Install Chromium test workspace
working-directory: tests/e2e
run: |
Expand All @@ -345,15 +346,27 @@ jobs:
--config "hugo.yaml,${RUNNER_TEMP}/ai-version-config.json,tests/e2e/ai-enabled.yaml" \
--destination "${RUNNER_TEMP}/ai-site" \
--cleanDestinationDir --gc --minify --environment production
- name: Build AI-disabled rollback fixture
run: |
python3 scripts/versioning.py config \
--version latest \
--site-origin http://127.0.0.1:4175/ \
--historical-origin "$PRODUCTION_ORIGIN" \
--output "${RUNNER_TEMP}/ai-disabled-version-config.json"
hugo \
--config "hugo.yaml,${RUNNER_TEMP}/ai-disabled-version-config.json,tests/e2e/ai-disabled.yaml" \
--destination "${RUNNER_TEMP}/ai-disabled-site" \
--cleanDestinationDir --gc --minify --environment production
- name: Run blocking Chromium contracts
working-directory: tests/e2e
env:
SITE_ROOT: ${{ github.workspace }}/public-site
SITE_ROOT: ${{ runner.temp }}/public-site
AI_SITE_ROOT: ${{ runner.temp }}/ai-site
AI_DISABLED_SITE_ROOT: ${{ runner.temp }}/ai-disabled-site
EXPECTED_VERSIONS: ${{ needs.prepare.outputs.selection }}
run: npm run test:ci
- name: Upload E2E report
if: always()
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: playwright-report-${{ github.run_id }}-${{ github.run_attempt }}
Expand All @@ -372,7 +385,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ needs.prepare.outputs.source_sha }}
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
Expand All @@ -381,7 +394,7 @@ jobs:
cache-dependency-path: tests/e2e/package-lock.json
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: hugegraph-site-${{ needs.prepare.outputs.artifact_prefix }}-${{ github.run_id }}-${{ github.run_attempt }}
name: hugegraph-site-${{ needs.prepare.outputs.artifact_prefix }}-${{ github.run_id }}
path: public-site
- name: Capture advisory visual states
working-directory: tests/e2e
Expand All @@ -392,7 +405,7 @@ jobs:
npx playwright install --with-deps chromium
npm run test:visual
- name: Upload advisory visual evidence
if: always()
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: visual-evidence-${{ github.run_id }}-${{ github.run_attempt }}
Expand All @@ -402,8 +415,8 @@ jobs:

# Required check name in .asf.yaml. It gates artifacts without write access.
deploy:
if: always()
needs: [prepare, build, aggregate, e2e]
if: ${{ !cancelled() }}
needs: [prepare, build, aggregate]
runs-on: ubuntu-latest
timeout-minutes: 5
permissions: { contents: read }
Expand All @@ -413,12 +426,10 @@ jobs:
PREPARE_RESULT: ${{ needs.prepare.result }}
BUILD_RESULT: ${{ needs.build.result }}
AGGREGATE_RESULT: ${{ needs.aggregate.result }}
E2E_RESULT: ${{ needs.e2e.result }}
run: |
test "$PREPARE_RESULT" = success
test "$BUILD_RESULT" = success
test "$AGGREGATE_RESULT" = success
test "$E2E_RESULT" = success

publish:
if: needs.prepare.outputs.publish_branch != ''
Expand All @@ -429,7 +440,7 @@ jobs:
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: hugegraph-site-${{ needs.prepare.outputs.artifact_prefix }}-${{ github.run_id }}-${{ github.run_attempt }}
name: hugegraph-site-${{ needs.prepare.outputs.artifact_prefix }}-${{ github.run_id }}
path: public-site
- name: Verify fixed publication target
env:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ GEMINI.md
.gemini/
WARP.md
/.goal-task

__pycache__/
*.pyc
5 changes: 5 additions & 0 deletions .htaccess
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
RedirectMatch 404 "(?i)(?:^|/)\.git(?:/|$)"
ErrorDocument 404 /404.html
# Reuse the existing HugeGraph Kapa/hCaptcha integration, PR #459.
# Source: https://github.com/apache/hugegraph-doc/commit/7662b8afb64265ed7412f6d704b8adfa9a836fff
# Preserve ASF default CSP; no Google CAPTCHA or optional metrics domains.
# Existing deployment evidence is not a separate VP Privacy approval record.
SetEnv CSP_PROJECT_DOMAINS "https://widget.kapa.ai https://proxy.kapa.ai https://kapa-widget-proxy-la7dkmplpq-uc.a.run.app https://hcaptcha.com https://*.hcaptcha.com"
Loading