ci: trigger workflow on PR with build-only validation
Some checks failed
CI / Deploy (pull_request) Has been skipped
PR → Build → WiFi/USB Deploy → LGTM / Build & Deploy to iPhone (WiFi/USB) (pull_request) Failing after 2m37s
PR → Build → WiFi/USB Deploy → LGTM / Wait for LGTM comment (pull_request) Has been skipped
Admin Web Docker / Docker Build Validation (pull_request) Failing after 28s
Admin Web Docker / Semantic Release (pull_request) Has been skipped
CI / Detect Changes (pull_request) Successful in 4s
Admin Web Docker / Build & Push Docker Image (pull_request) Has been skipped
CI / Admin Web CI (pull_request) Failing after 38s
CI / YouTube Worker (pull_request) Has been skipped

This commit is contained in:
Millian Lamiaux
2026-07-12 22:50:35 +02:00
parent cb86bf55b3
commit 3dd044029e
2 changed files with 167 additions and 6 deletions

View File

@@ -3,6 +3,10 @@ name: Admin Web Docker
on:
push:
branches: [main]
pull_request:
paths:
- 'admin-web/**'
- '.github/workflows/admin-web-docker.yml'
workflow_dispatch:
concurrency:
@@ -13,15 +17,46 @@ env:
NODE_VERSION: "22"
jobs:
build-validation:
name: Docker Build Validation
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Install Docker CLI
run: sudo apt-get update -qq && sudo apt-get install -y -qq docker.io
- name: Build admin-web image (no push)
env:
NEXT_PUBLIC_SUPABASE_URL: ${{ vars.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ vars.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
run: |
set -e
docker build \
--file admin-web/Dockerfile \
--build-arg "NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL}" \
--build-arg "NEXT_PUBLIC_SUPABASE_ANON_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY}" \
--tag "tabatago-admin-web:pr-validation" \
admin-web
semantic-release:
name: Semantic Release
runs-on: ubuntu-latest
timeout-minutes: 10
if: |
github.event_name == 'workflow_dispatch' ||
github.event_name != 'pull_request' &&
(
!contains(github.event.head_commit.message, '[skip ci]') &&
!contains(github.event.head_commit.message, '[ci skip]')
github.event_name == 'workflow_dispatch' ||
(
!contains(github.event.head_commit.message, '[skip ci]') &&
!contains(github.event.head_commit.message, '[ci skip]')
)
)
outputs:
released: ${{ steps.release.outputs.released }}

View File

@@ -263,9 +263,9 @@ check_workflow_valid() {
yaml_valid ".github/workflows/admin-web-docker.yml" "admin-web-docker.yml is valid YAML"
}
# --- workflow: exactly 2 jobs --------------------------------------- #
# --- workflow: exactly 3 jobs --------------------------------------- #
check_workflow_jobs() {
local label="workflow has exactly 2 jobs: semantic-release + build-and-push"
local label="workflow has exactly 3 jobs: build-validation + semantic-release + build-and-push"
local f=".github/workflows/admin-web-docker.yml"
if [[ ! -f "$f" ]]; then
fail "$label" "file missing"
@@ -281,7 +281,7 @@ print(','.join(sorted(jobs)))
fail "$label" "could not parse jobs"
return
fi
if [[ "$out" == "build-and-push,semantic-release" ]]; then
if [[ "$out" == "build-and-push,build-validation,semantic-release" ]]; then
pass "$label"
else
fail "$label" "jobs=[$out]"
@@ -495,6 +495,126 @@ check_git_commit_prefix() {
fi
}
# =================================================================== #
# PR BUILD-VALIDATION FEATURE CHECKS
# (trigger pull_request + job build-validation build-only/no-secret)
# =================================================================== #
# --- workflow: pull_request trigger with admin-web/** path filter --- #
check_pr_trigger() {
local f=".github/workflows/admin-web-docker.yml"
local label="workflow triggers on pull_request with admin-web/** path filter"
if [[ ! -f "$f" ]]; then
fail "$label" "file missing"
return
fi
local out
out=$(python3 -c "
import yaml,sys
d=yaml.safe_load(open(sys.argv[1]))
on=d.get(True) or d.get('on') or {}
if not isinstance(on,dict): print('NO-PR: on not a dict'); sys.exit()
pr=on.get('pull_request')
if pr is None: print('NO-PR: no pull_request key'); sys.exit()
paths=(pr.get('paths') if isinstance(pr,dict) else None) or []
print('|'.join(str(p) for p in paths))
" "$f" 2>/dev/null || echo "ERR")
if echo "$out" | grep -Eq 'admin-web/\*\*'; then
pass "$label"
else
fail "$label" "pull_request.paths=[$out]"
fi
}
# --- build-validation job: exists + if: pull_request ---------------- #
check_build_validation_if() {
local f=".github/workflows/admin-web-docker.yml"
local label="build-validation job if: github.event_name == 'pull_request'"
if [[ ! -f "$f" ]]; then
fail "$label" "file missing"
return
fi
local cond
cond=$(python3 -c "
import yaml,sys
d=yaml.safe_load(open(sys.argv[1]))
bv=d.get('jobs',{}).get('build-validation',{})
print(bv.get('if','') or '')
" "$f" 2>/dev/null || true)
if echo "$cond" | grep -Eq "github\.event_name\s*==\s*'pull_request'"; then
pass "$label"
else
fail "$label" "if='$cond'"
fi
}
# --- build-validation job: NO docker push (build-only) -------------- #
check_build_validation_no_push() {
local f=".github/workflows/admin-web-docker.yml"
local label="build-validation does NOT docker push (build-only)"
if [[ ! -f "$f" ]]; then
fail "$label" "file missing"
return
fi
local out
out=$(python3 -c "
import yaml,sys,json
d=yaml.safe_load(open(sys.argv[1]))
bv=d.get('jobs',{}).get('build-validation',{})
blob=json.dumps(bv)
print('PUSH' if 'docker push' in blob else 'NO-PUSH')
" "$f" 2>/dev/null || echo "ERR")
if [[ "$out" == "NO-PUSH" ]]; then
pass "$label"
else
fail "$label" "docker push found in build-validation job"
fi
}
# --- build-validation job: NO secrets (public vars only) ------------ #
check_build_validation_no_secrets() {
local f=".github/workflows/admin-web-docker.yml"
local label="build-validation references no secrets (build-only, public vars only)"
if [[ ! -f "$f" ]]; then
fail "$label" "file missing"
return
fi
local out
out=$(python3 -c "
import yaml,sys,json
d=yaml.safe_load(open(sys.argv[1]))
bv=d.get('jobs',{}).get('build-validation',{})
blob=json.dumps(bv)
print('SECRET' if 'secrets.' in blob else 'NO-SECRET')
" "$f" 2>/dev/null || echo "ERR")
if [[ "$out" == "NO-SECRET" ]]; then
pass "$label"
else
fail "$label" "secrets.* referenced in build-validation job"
fi
}
# --- semantic-release if excludes pull_request ---------------------- #
check_sr_excludes_pr() {
local f=".github/workflows/admin-web-docker.yml"
local label="semantic-release if excludes pull_request"
if [[ ! -f "$f" ]]; then
fail "$label" "file missing"
return
fi
local cond
cond=$(python3 -c "
import yaml,sys
d=yaml.safe_load(open(sys.argv[1]))
print(d.get('jobs',{}).get('semantic-release',{}).get('if','') or '')
" "$f" 2>/dev/null || true)
if echo "$cond" | grep -Eq "github\.event_name\s*!=\s*'pull_request'"; then
pass "$label"
else
fail "$label" "if missing pull_request exclusion (if='$cond')"
fi
}
# =================================================================== #
# RUN ALL
# =================================================================== #
@@ -525,6 +645,12 @@ check_buildargs_source
check_actions_pinned
check_git_branch
check_git_commit_prefix
# PR build-validation feature checks
check_pr_trigger
check_build_validation_if
check_build_validation_no_push
check_build_validation_no_secrets
check_sr_excludes_pr
echo ""
echo "# Summary: $PASS_COUNT passed, $FAIL_COUNT failed"