mirror of
https://github.com/apache/superset.git
synced 2026-08-12 11:11:01 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f453eead9 | ||
|
|
c39c44d0a5 | ||
|
|
eceb7e2355 | ||
|
|
f4b89b6d0d | ||
|
|
570d29d618 | ||
|
|
7d3b82f556 |
@@ -45,5 +45,8 @@ jobs:
|
||||
- name: Run Script
|
||||
run: bash .github/workflows/github-action-validator.sh
|
||||
|
||||
- name: Test docs-deploy freshness gate
|
||||
run: bash .github/workflows/scripts/check-docs-deploy-freshness.test.sh
|
||||
|
||||
- name: Check for security issues on GHA workflows
|
||||
uses: zizmorcore/zizmor-action@6599ee8b7a49aef6a770f63d261d214911a7ce02 # v0.6.0
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Shared freshness gate used by the Docs Deployment workflow
|
||||
# (superset-docs-deploy.yml) both up front (check-freshness) and again right
|
||||
# before the deploy step (recheck-freshness). Writes an output declaring
|
||||
# whether BUILD_SHA is still master's current tip, so a superseded run can
|
||||
# skip cleanly instead of racing (and clobbering, or being force-cancelled
|
||||
# by) a fresher run.
|
||||
#
|
||||
# Required env vars:
|
||||
# BUILD_SHA - the commit SHA this run is building
|
||||
# REPO - "owner/repo" to query, e.g. github.repository
|
||||
# OUTPUT_NAME - the GITHUB_OUTPUT key to write, e.g. "is-current"
|
||||
# GITHUB_OUTPUT - path to append outputs to (set by the Actions runner)
|
||||
# Optional env vars:
|
||||
# EVENT_NAME - if "workflow_dispatch", bypasses the check and always
|
||||
# reports current, since a manual dispatch is a deliberate,
|
||||
# one-off action rather than something racing other triggers
|
||||
# GH_TOKEN - passed through to `gh`, needed to call the GitHub API
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [ "${EVENT_NAME:-}" = "workflow_dispatch" ]; then
|
||||
echo "${OUTPUT_NAME}=true" >>"$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
latest_sha="$(gh api "repos/${REPO}/commits/master" --jq .sha)"
|
||||
if [ "${latest_sha}" = "${BUILD_SHA}" ]; then
|
||||
echo "${OUTPUT_NAME}=true" >>"$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "${OUTPUT_NAME}=false" >>"$GITHUB_OUTPUT"
|
||||
echo "::notice::master has moved on to ${latest_sha} since ${BUILD_SHA} was triggered — skipping this stale run."
|
||||
fi
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Exercises check-docs-deploy-freshness.sh against a stubbed `gh`, covering
|
||||
# the dispatch-bypass, current-tip and stale-tip branches so the output
|
||||
# contract (is-current / still-current) can't silently regress. Run
|
||||
# directly, no extra tooling required:
|
||||
# bash .github/workflows/scripts/check-docs-deploy-freshness.test.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
script_under_test="${script_dir}/check-docs-deploy-freshness.sh"
|
||||
|
||||
failures=0
|
||||
|
||||
# Runs the script under test with a stubbed `gh` reporting $1 as master's
|
||||
# latest sha, asserting that GITHUB_OUTPUT ends up containing exactly $4.
|
||||
run_case() {
|
||||
local case_name="$1"
|
||||
local latest_sha="$2"
|
||||
local build_sha="$3"
|
||||
local event_name="$4"
|
||||
local expected_line="$5"
|
||||
|
||||
local workdir
|
||||
workdir="$(mktemp -d)"
|
||||
trap 'rm -rf "${workdir}"' RETURN
|
||||
|
||||
# Fake `gh` that just echoes back the requested "latest" sha regardless of
|
||||
# arguments, so the script under test never touches the network.
|
||||
cat >"${workdir}/gh" <<EOF
|
||||
#!/bin/bash
|
||||
echo '${latest_sha}'
|
||||
EOF
|
||||
chmod +x "${workdir}/gh"
|
||||
|
||||
local output_file="${workdir}/github_output"
|
||||
: >"${output_file}"
|
||||
|
||||
if PATH="${workdir}:${PATH}" \
|
||||
GITHUB_OUTPUT="${output_file}" \
|
||||
OUTPUT_NAME="is-current" \
|
||||
REPO="apache/superset" \
|
||||
BUILD_SHA="${build_sha}" \
|
||||
EVENT_NAME="${event_name}" \
|
||||
GH_TOKEN="fake-token" \
|
||||
bash "${script_under_test}"; then
|
||||
:
|
||||
else
|
||||
echo "FAIL (${case_name}): script exited non-zero"
|
||||
failures=$((failures + 1))
|
||||
return
|
||||
fi
|
||||
|
||||
local actual
|
||||
actual="$(cat "${output_file}")"
|
||||
if [ "${actual}" = "${expected_line}" ]; then
|
||||
echo "PASS (${case_name})"
|
||||
else
|
||||
echo "FAIL (${case_name}): expected '${expected_line}', got '${actual}'"
|
||||
failures=$((failures + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
# `gh` prints "should-not-be-called" for the dispatch case above the trick:
|
||||
# it's never actually invoked since the bypass short-circuits before the
|
||||
# `gh api` call, but the fake still needs a body.
|
||||
run_case "workflow_dispatch bypasses the check" \
|
||||
"unused" "abc123" "workflow_dispatch" \
|
||||
"is-current=true"
|
||||
|
||||
run_case "build sha matches master's tip" \
|
||||
"abc123" "abc123" "push" \
|
||||
"is-current=true"
|
||||
|
||||
run_case "build sha is stale" \
|
||||
"def456" "abc123" "push" \
|
||||
"is-current=false"
|
||||
|
||||
if [ "${failures}" -gt 0 ]; then
|
||||
echo "${failures} case(s) failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "All cases passed"
|
||||
@@ -18,16 +18,6 @@ on:
|
||||
|
||||
workflow_dispatch: {}
|
||||
|
||||
# Serialize deploys: the action pushes to apache/superset-site without
|
||||
# rebasing, so concurrent runs race on the final push and the loser fails
|
||||
# with `! [rejected] asf-site -> asf-site (fetch first)`. Cancel any
|
||||
# in-progress run as soon as a newer one starts — the destination repo
|
||||
# isn't touched until the final push step, so canceling mid-build is safe,
|
||||
# and the freshest content always wins.
|
||||
concurrency:
|
||||
group: docs-deploy-asf-site
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -47,17 +37,69 @@ jobs:
|
||||
|
||||
env:
|
||||
SUPERSET_SITE_BUILD: ${{ (secrets.SUPERSET_SITE_BUILD != '' && secrets.SUPERSET_SITE_BUILD != '') || '' }}
|
||||
|
||||
# Master gets frequent, sometimes bursty pushes, and each one can trigger a
|
||||
# deploy attempt. Rather than let every superseded attempt get force-killed
|
||||
# by the build-deploy concurrency group below (which shows up as a
|
||||
# `cancelled` — i.e. red/failing-looking — check on that commit), have each
|
||||
# run check up front whether it's still building master's current tip and,
|
||||
# if not, skip cleanly. Deliberately outside the docs-deploy-asf-site
|
||||
# concurrency group so it runs immediately for every trigger without
|
||||
# blocking or being blocked by anything.
|
||||
check-freshness:
|
||||
runs-on: ubuntu-26.04
|
||||
outputs:
|
||||
is-current: ${{ steps.check.outputs.is-current }}
|
||||
steps:
|
||||
# Sparse checkout: this job's only job is to be fast, so it fetches
|
||||
# nothing but the freshness-check script itself.
|
||||
- name: Checkout freshness-check script
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
sparse-checkout: |
|
||||
.github/workflows/scripts
|
||||
sparse-checkout-cone-mode: false
|
||||
- name: "Check whether this is still master's current commit"
|
||||
id: check
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BUILD_SHA: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
REPO: ${{ github.repository }}
|
||||
OUTPUT_NAME: is-current
|
||||
run: .github/workflows/scripts/check-docs-deploy-freshness.sh
|
||||
|
||||
build-deploy:
|
||||
needs: config
|
||||
needs: [config, check-freshness]
|
||||
# Only the run for master's current tip proceeds; anything superseded
|
||||
# already skipped at check-freshness above instead of landing here.
|
||||
# For workflow_run triggers, only deploy when the triggering run originated
|
||||
# from this repository (not a fork), ensuring the checked-out code and any
|
||||
# local actions executed with deploy credentials are trusted.
|
||||
if: >-
|
||||
needs.config.outputs.has-secrets &&
|
||||
needs.check-freshness.outputs.is-current == 'true' &&
|
||||
(github.event_name != 'workflow_run' ||
|
||||
github.event.workflow_run.head_repository.full_name == github.repository)
|
||||
name: Build & Deploy
|
||||
runs-on: ubuntu-26.04
|
||||
# Serialize deploys: the action pushes to apache/superset-site without
|
||||
# rebasing, so concurrent runs race on the final push and the loser fails
|
||||
# with `! [rejected] asf-site -> asf-site (fetch first)`. Queue instead of
|
||||
# canceling: a run that already passed check-freshness can still be
|
||||
# sitting in the queue for a runner when a newer run starts and finishes
|
||||
# first. cancel-in-progress would let that stale, queued run kill the
|
||||
# newer run's in-progress deploy the moment it's finally scheduled, and
|
||||
# then skip itself at the re-check below — losing the deploy entirely.
|
||||
# Queuing means the stale run just waits its turn and then no-ops at the
|
||||
# re-check, so the fresher content that already deployed is never
|
||||
# clobbered or lost. The check-freshness gate above means it should be
|
||||
# rare for more than one run to reach this point, so the queue stays
|
||||
# short in practice.
|
||||
concurrency:
|
||||
group: docs-deploy-asf-site
|
||||
cancel-in-progress: false
|
||||
steps:
|
||||
- name: "Checkout ${{ github.event.workflow_run.head_sha || github.sha }}"
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
@@ -121,7 +163,24 @@ jobs:
|
||||
working-directory: docs
|
||||
run: |
|
||||
yarn build
|
||||
# The check-freshness job above narrows the window but doesn't close it: an
|
||||
# older run can observe is-current=true, then sit through this build while a
|
||||
# newer run's own freshness check also passes and it deploys and finishes
|
||||
# first. If this (stale) run then wins entry into the concurrency group, it
|
||||
# would overwrite the newer content that already deployed. Re-check right
|
||||
# before the one step that actually mutates superset-site, so a stale run
|
||||
# skips deploying instead of clobbering a fresher one that already ran.
|
||||
- name: "Re-check freshness immediately before deploying"
|
||||
id: recheck-freshness
|
||||
if: github.event_name != 'workflow_dispatch'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BUILD_SHA: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
REPO: ${{ github.repository }}
|
||||
OUTPUT_NAME: still-current
|
||||
run: .github/workflows/scripts/check-docs-deploy-freshness.sh
|
||||
- name: deploy docs
|
||||
if: github.event_name == 'workflow_dispatch' || steps.recheck-freshness.outputs.still-current == 'true'
|
||||
uses: ./.github/actions/github-action-push-to-another-repository
|
||||
env:
|
||||
API_TOKEN_GITHUB: ${{ secrets.SUPERSET_SITE_BUILD }}
|
||||
|
||||
Reference in New Issue
Block a user