Skip to content

Commit 3cef7a9

Browse files
authored
Merge branch 'main' into fix/embed-video-misplaced
2 parents dd306e1 + c5df7ee commit 3cef7a9

7 files changed

Lines changed: 105 additions & 45 deletions

File tree

.github/actions/validate-requirements/action.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
name: "Validate requirements"
22

33
description: |
4-
Reject changes to `requirements.txt` unless the latest commit that touched
5-
the file in the compare range was authored by an allowed bot.
4+
Reject direct edits to `requirements.txt` by humans: the action fails if
5+
any commit touching the file in the compare range appears to be authored by a
6+
human or otherwise not from an allowed bot (unless the commit message exactly
7+
matches the canonical bot commit message).
68
79
inputs:
810
allowed_bots:

.github/actions/validate-requirements/check.sh

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
set -euo pipefail
33
IFS=$'\n\t'
44

5+
# Mode: "validate" (default, exits non-zero on human edit) or "detect" (outputs to GITHUB_OUTPUT)
6+
MODE="${MODE:-validate}"
57
ALLOWED_BOTS="${ALLOWED_BOTS:-github-actions[bot],dependabot[bot]}"
68

79
# Determine the comparison range
@@ -24,60 +26,81 @@ else
2426
COMPARE_RANGE="HEAD~1..HEAD"
2527
fi
2628

27-
# If requirements.txt changed in comparison range, ensure latest change's commit
28-
# was authored by an allowed bot, or the latest commit message exactly matches
29-
# the canonical bot commit message, or fallback to any bot-authored commit.
30-
if git diff --name-only $COMPARE_RANGE | grep -q "^requirements.txt$"; then
31-
latest_sha=$(git log -1 --pretty=format:'%H' $COMPARE_RANGE -- requirements.txt || true)
29+
# Check if requirements.txt changed
30+
if ! git diff --name-only $COMPARE_RANGE | grep -q "^requirements.txt$"; then
31+
echo "'requirements.txt' unchanged"
32+
if [ "$MODE" = "detect" ]; then
33+
echo "is_human_edit=false" >> "${GITHUB_OUTPUT:-/dev/stdout}"
34+
fi
35+
exit 0
36+
fi
3237

33-
if [ -z "$latest_sha" ]; then
34-
echo "::error::No commits found touching requirements.txt in range $COMPARE_RANGE"
35-
exit 1
38+
# Check if requirements.txt differs from base (net change across all commits in range)
39+
if [ -n "$is_pr" ] && [ -n "$has_base_ref" ] && [ -n "$origin_base_ref_exists" ]; then
40+
BASE_REF_PARSED="origin/${GITHUB_BASE_REF}"
41+
if git diff --quiet "$BASE_REF_PARSED" HEAD -- requirements.txt; then
42+
echo "requirements.txt touched but matches base branch (likely reverted): OK"
43+
if [ "$MODE" = "detect" ]; then
44+
echo "is_human_edit=false" >> "${GITHUB_OUTPUT:-/dev/stdout}"
45+
fi
46+
exit 0
3647
fi
48+
fi
3749

38-
latest_author=$(git show -s --format='%an' "$latest_sha")
39-
latest_committer=$(git show -s --format='%cn' "$latest_sha")
40-
latest_message=$(git show -s --format='%B' "$latest_sha")
50+
# Get latest commit that touched requirements.txt
51+
latest_sha=$(git log -1 --pretty=format:'%H' $COMPARE_RANGE -- requirements.txt || true)
4152

42-
echo "Latest commit touching requirements.txt: $latest_sha"
43-
echo " author: $latest_author"
44-
echo " committer: $latest_committer"
45-
echo " message: $(echo "$latest_message" | head -n1)"
53+
if [ -z "$latest_sha" ]; then
54+
echo "::error::No commits found touching requirements.txt in range $COMPARE_RANGE"
55+
if [ "$MODE" = "detect" ]; then
56+
echo "is_human_edit=false" >> "${GITHUB_OUTPUT:-/dev/stdout}"
57+
fi
58+
exit 1
59+
fi
4660

47-
# Build a grep-friendly regex from comma-separated allowed bots
48-
allowed_regex=$(echo "$ALLOWED_BOTS" | sed 's/,/\\|/g')
61+
latest_author=$(git show -s --format='%an' "$latest_sha")
62+
latest_committer=$(git show -s --format='%cn' "$latest_sha")
63+
latest_message=$(git show -s --format='%B' "$latest_sha")
64+
latest_subject=$(echo "$latest_message" | head -n1 | sed -e 's/[[:space:]]*$//')
4965

50-
# 1) author or committer is allowed bot
51-
if echo "$latest_author" | grep -qE "^($allowed_regex)$" || echo "$latest_committer" | grep -qE "^($allowed_regex)$"; then
52-
echo "Latest change by allowed bot: OK"
53-
exit 0
54-
fi
66+
# Build a grep-friendly regex from comma-separated allowed bots
67+
allowed_regex=$(echo "$ALLOWED_BOTS" | sed 's/,/\\|/g')
5568

56-
# 2) latest commit message exactly equals canonical message
57-
if [ -n "${COMMIT_MSG_FILE:-}" ] && [ -f "$COMMIT_MSG_FILE" ]; then
58-
canonical_msg=$(sed -n '1p' "$COMMIT_MSG_FILE" | tr -d '\r')
59-
# Compare exact first-line equality (trim trailing newline/space)
60-
latest_first_line=$(echo "$latest_message" | head -n1 | sed -e 's/[[:space:]]*$//')
61-
if [ "$latest_first_line" = "$canonical_msg" ]; then
62-
echo "Latest commit message exactly matches canonical bot message: OK"
63-
exit 0
64-
fi
69+
# Check 1: author or committer is allowed bot
70+
if echo "$latest_author" | grep -qE "^($allowed_regex)$" || echo "$latest_committer" | grep -qE "^($allowed_regex)$"; then
71+
echo "Latest change by allowed bot: OK"
72+
if [ "$MODE" = "detect" ]; then
73+
echo "is_human_edit=false" >> "${GITHUB_OUTPUT:-/dev/stdout}"
6574
fi
75+
exit 0
76+
fi
6677

67-
# 3) fallback: any commit touching the file in range has allowed bot author or committer
68-
if git log $COMPARE_RANGE --pretty=format:'%an|%cn' -- requirements.txt | grep -qE "($allowed_regex)"; then
69-
echo "Found a bot-authored/committed change touching requirements.txt in the range: OK"
78+
# Check 2: commit message exactly matches canonical message
79+
if [ -n "${COMMIT_MSG_FILE:-}" ] && [ -f "$COMMIT_MSG_FILE" ]; then
80+
canonical_msg=$(sed -n '1p' "$COMMIT_MSG_FILE" | tr -d '\r')
81+
if [ "$latest_subject" = "$canonical_msg" ]; then
82+
echo "Latest commit message exactly matches canonical bot message: OK"
83+
if [ "$MODE" = "detect" ]; then
84+
echo "is_human_edit=false" >> "${GITHUB_OUTPUT:-/dev/stdout}"
85+
fi
7086
exit 0
7187
fi
88+
fi
7289

90+
# Human edit detected
91+
if [ "$MODE" = "detect" ]; then
92+
echo "is_human_edit=true" >> "${GITHUB_OUTPUT:-/dev/stdout}"
93+
echo "offender_author=$latest_author" >> "${GITHUB_OUTPUT:-/dev/stdout}"
94+
echo "offender_subject=$latest_subject" >> "${GITHUB_OUTPUT:-/dev/stdout}"
95+
echo "Human edit detected"
96+
exit 0
97+
else
7398
echo "::error::You may NOT edit 'requirements.txt'"
7499
echo "::warning::Undo your changes to requirements.txt, so robot can maintain it."
75100
echo "::notice::To pin dependencies, use 'poetry add <package-name>'."
76101
echo "Latest commit: $latest_sha"
77102
echo "Latest author: $latest_author"
78103
echo "Latest committer: $latest_committer"
79-
echo "Latest message: $(echo "$latest_message" | head -n1)"
104+
echo "Latest message: \"$latest_subject\""
80105
exit 1
81106
fi
82-
83-
echo "'requirements.txt' unchanged (or latest change by allowed bot/marker)"

.github/workflows/requirements-validate.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ on:
99
jobs:
1010
reject-requirements-drift:
1111
runs-on: ubuntu-latest
12+
env:
13+
COMMIT_MSG_FILE: .github/commit-messages/requirements_update.txt
1214

1315
# Skip if the last commit was from the bot (prevent unnecessary check)
1416
if: github.event.head_commit.author.name != 'github-actions[bot]'
@@ -23,4 +25,5 @@ jobs:
2325
uses: ./.github/actions/validate-requirements
2426
with:
2527
allowed_bots: 'github-actions[bot],dependabot[bot]'
28+
commit_message_file: ${{ env.COMMIT_MSG_FILE }}
2629

.github/workflows/requirments-sync.yml

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,37 @@ jobs:
4949
echo "has_change=true" >> $GITHUB_OUTPUT
5050
fi
5151
52-
commit-requirements-delta:
52+
prevent-bot-commit-if-human-edit:
5353
runs-on: ubuntu-latest
5454
needs: detect-requirements-delta
5555
if: needs.detect-requirements-delta.outputs.has_change == 'true'
56+
outputs:
57+
is_human_edit: ${{ steps.check.outputs.is_human_edit }}
58+
offender_author: ${{ steps.check.outputs.offender_author }}
59+
offender_subject: ${{ steps.check.outputs.offender_subject }}
60+
env:
61+
ALLOWED_BOTS: 'github-actions[bot],dependabot[bot]'
62+
COMMIT_MSG_FILE: .github/commit-messages/requirements_update.txt
63+
64+
steps:
65+
- name: Checkout code
66+
uses: actions/checkout@v4
67+
with:
68+
ref: ${{ github.head_ref || github.ref_name }}
69+
fetch-depth: 0
70+
71+
- name: Check for human edits
72+
id: check
73+
env:
74+
MODE: detect
75+
run: bash ./.github/actions/validate-requirements/check.sh
76+
77+
commit-requirements-delta:
78+
runs-on: ubuntu-latest
79+
needs: [detect-requirements-delta, prevent-bot-commit-if-human-edit]
80+
if: needs.detect-requirements-delta.outputs.has_change == 'true' && needs.prevent-bot-commit-if-human-edit.outputs.is_human_edit == 'false'
81+
env:
82+
COMMIT_MSG_FILE: .github/commit-messages/requirements_update.txt
5683

5784
steps:
5885
- name: Checkout code
@@ -83,10 +110,11 @@ jobs:
83110
if git diff --staged --quiet; then
84111
echo "No changes to requirements.txt"
85112
else
86-
commit_msg=$(sed -n '1p' .github/commit-messages/requirements_update.txt 2>/dev/null | tr -d '\r')
113+
commit_msg=$(sed -n '1p' "$COMMIT_MSG_FILE" 2>/dev/null | tr -d '\r')
87114
if [ -z "$commit_msg" ]; then
88-
echo "::error::Missing or empty canonical commit message file: .github/commit-messages/requirements_update.txt"
115+
echo "::error::Missing or empty canonical commit message file: $COMMIT_MSG_FILE"
89116
exit 1
90117
fi
91118
git commit -m "$commit_msg"
119+
git push
92120
fi

.github/workflows/validate-requirements.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ on:
77
jobs:
88
check-requirements:
99
runs-on: ubuntu-latest
10+
env:
11+
COMMIT_MSG_FILE: .github/commit-messages/requirements_update.txt
1012

1113
steps:
1214
- name: Checkout code
@@ -18,4 +20,5 @@ jobs:
1820
uses: ./.github/actions/validate-requirements
1921
with:
2022
allowed_bots: 'github-actions[bot],dependabot[bot]'
23+
commit_message_file: ${{ env.COMMIT_MSG_FILE }}
2124

poetry.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ mkdocs-exclude-search==0.6.6 ; python_version >= "3.10" and python_version < "3.
115115
mkdocs-include-markdown-plugin==5.1.0 ; python_version >= "3.10" and python_version < "3.13" \
116116
--hash=sha256:4a1b8d79a0e1b6fd357ca8013a6d1701c755ada4acb74ee97b0642d1afe6756e \
117117
--hash=sha256:e9ca188ab1d86f5fc4a6b96ce8c85acf6e25f114897868041056ec7945f29f65
118-
mkdocs-tacc==1.0.2 ; python_version >= "3.10" and python_version < "3.13" \
119-
--hash=sha256:2beb36590dc00ec8f815ba59bcf6a3e876ffe2106bcc4a235db9ea04cb2a1601 \
120-
--hash=sha256:9eb65c4701206fdc17ebbc2555c2750ef3de8de64ed3142b0e45f5df32390e4e
118+
mkdocs-tacc==1.0.1 ; python_version >= "3.10" and python_version < "3.13" \
119+
--hash=sha256:08b8e0b1ab5bdcdfea493c2f18077723b36569afdd71a23a5d097fb7942799ea \
120+
--hash=sha256:f14ac8d3833bb43447cdb91210f6179e85fe5bef92f7d948ac9c50e41ec8e6c0
121121
mkdocs==1.4.3 ; python_version >= "3.10" and python_version < "3.13" \
122122
--hash=sha256:5955093bbd4dd2e9403c5afaf57324ad8b04f16886512a3ee6ef828956481c57 \
123123
--hash=sha256:6ee46d309bda331aac915cd24aab882c179a933bd9e77b80ce7d2eaaa3f689dd

0 commit comments

Comments
 (0)