99 lines
3.3 KiB
YAML
99 lines
3.3 KiB
YAML
|
|
name: PR build (required check)
|
||
|
|
|
||
|
|
# Monorepo port of the app repos' pr-build.yml: ONE workflow, ONE stable
|
||
|
|
# required-check name (`gate`), any number of domains. A `changes` job diffs
|
||
|
|
# the PR against its base; per-domain jobs run only for domains the PR
|
||
|
|
# touches; `gate` reduces their results into the single status branch
|
||
|
|
# protection requires.
|
||
|
|
#
|
||
|
|
# Deliberately NOT path-filtered at the workflow level: a path-filtered
|
||
|
|
# required check that never fires leaves the PR stuck "expected -- waiting for
|
||
|
|
# status" forever, so auto-merge never proceeds. An always-running gate whose
|
||
|
|
# domain jobs skip cleanly gives the same compute savings without the
|
||
|
|
# deadlock.
|
||
|
|
#
|
||
|
|
# One-time web UI setup (Settings -> Branches, rules for `dev` and `main`):
|
||
|
|
# -> enable "Enable Status Check", list this workflow's "gate" job
|
||
|
|
# -> merge style: squash
|
||
|
|
# Then on a ready PR: "Auto merge when checks succeed".
|
||
|
|
|
||
|
|
on:
|
||
|
|
pull_request:
|
||
|
|
branches: [dev, main]
|
||
|
|
|
||
|
|
concurrency:
|
||
|
|
group: pr-build-${{ github.event.pull_request.number }}
|
||
|
|
cancel-in-progress: true
|
||
|
|
|
||
|
|
jobs:
|
||
|
|
changes:
|
||
|
|
runs-on: docker
|
||
|
|
outputs:
|
||
|
|
backend: ${{ steps.diff.outputs.backend }}
|
||
|
|
frontend: ${{ steps.diff.outputs.frontend }}
|
||
|
|
observability: ${{ steps.diff.outputs.observability }}
|
||
|
|
steps:
|
||
|
|
- uses: actions/checkout@v4
|
||
|
|
with:
|
||
|
|
# The PR base commit isn't reachable from a depth-1 clone; full
|
||
|
|
# history keeps the diff computable however far the branch diverged.
|
||
|
|
fetch-depth: 0
|
||
|
|
|
||
|
|
- name: Detect changed domains
|
||
|
|
id: diff
|
||
|
|
run: |
|
||
|
|
set -euo pipefail
|
||
|
|
base="${{ github.event.pull_request.base.sha }}"
|
||
|
|
changed=$(git diff --name-only "$base" "$GITHUB_SHA")
|
||
|
|
echo "changed files:"; printf '%s\n' "$changed"
|
||
|
|
for d in backend frontend observability; do
|
||
|
|
if printf '%s\n' "$changed" | grep -q "^$d/"; then
|
||
|
|
echo "$d=true" >> "$GITHUB_OUTPUT"
|
||
|
|
else
|
||
|
|
echo "$d=false" >> "$GITHUB_OUTPUT"
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
build-backend:
|
||
|
|
needs: changes
|
||
|
|
if: needs.changes.outputs.backend == 'true'
|
||
|
|
uses: ./.forgejo/workflows/build.yml
|
||
|
|
with:
|
||
|
|
domain: backend
|
||
|
|
|
||
|
|
build-frontend:
|
||
|
|
needs: changes
|
||
|
|
if: needs.changes.outputs.frontend == 'true'
|
||
|
|
uses: ./.forgejo/workflows/build.yml
|
||
|
|
with:
|
||
|
|
domain: frontend
|
||
|
|
|
||
|
|
validate-observability:
|
||
|
|
needs: changes
|
||
|
|
if: needs.changes.outputs.observability == 'true'
|
||
|
|
uses: ./.forgejo/workflows/observability-validate.yml
|
||
|
|
|
||
|
|
gate:
|
||
|
|
name: gate
|
||
|
|
# always(): skipped domain jobs (nothing changed there) must not skip the
|
||
|
|
# gate itself -- the required check has to report on EVERY PR.
|
||
|
|
if: always()
|
||
|
|
needs: [changes, build-backend, build-frontend, validate-observability]
|
||
|
|
runs-on: docker
|
||
|
|
steps:
|
||
|
|
- name: Reduce domain results
|
||
|
|
run: |
|
||
|
|
set -euo pipefail
|
||
|
|
ok=1
|
||
|
|
for pair in \
|
||
|
|
"backend=${{ needs.build-backend.result }}" \
|
||
|
|
"frontend=${{ needs.build-frontend.result }}" \
|
||
|
|
"observability=${{ needs.validate-observability.result }}"; do
|
||
|
|
echo "$pair"
|
||
|
|
case "${pair#*=}" in
|
||
|
|
success|skipped) ;;
|
||
|
|
*) ok=0 ;;
|
||
|
|
esac
|
||
|
|
done
|
||
|
|
[ "$ok" = 1 ] || { echo "a changed domain's check failed"; exit 1; }
|