From c5bf34a7bb9ff50ed589308d5136d9c5f05aca6f Mon Sep 17 00:00:00 2001 From: George Sapkin Date: Sun, 30 Nov 2025 07:24:10 +0200 Subject: [PATCH 1/5] formal: allow passing optional repo path Use the optional repo path to simplify local use. Signed-off-by: George Sapkin --- .github/scripts/check_formalities.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/scripts/check_formalities.sh b/.github/scripts/check_formalities.sh index caf8a7d6..eb7a379b 100755 --- a/.github/scripts/check_formalities.sh +++ b/.github/scripts/check_formalities.sh @@ -13,6 +13,10 @@ EMOJI_FAIL=':x:' RET=0 +REPO_PATH=${1:+-C "$1"} +# shellcheck disable=SC2206 +REPO_PATH=($REPO_PATH) + if [ -f 'workflow_context/.github/scripts/ci_helpers.sh' ]; then source workflow_context/.github/scripts/ci_helpers.sh else @@ -228,32 +232,32 @@ main() { fi echo - for commit in $(git rev-list HEAD ^origin/"$BRANCH"); do + for commit in $(git "${REPO_PATH[@]}" rev-list HEAD ^origin/"$BRANCH"); do HEADER_SET=0 COMMIT="$commit" info "=== Checking commit '$commit'" - if git show --format='%P' -s "$commit" | grep -qF ' '; then + if git "${REPO_PATH[@]}" show --format='%P' -s "$commit" | grep -qF ' '; then output_fail 'Pull request should not include merge commits' RET=1 fi - author_name="$(git show -s --format=%aN "$commit")" - committer_name="$(git show -s --format=%cN "$commit")" + author_name="$(git "${REPO_PATH[@]}" show -s --format=%aN "$commit")" + committer_name="$(git "${REPO_PATH[@]}" show -s --format=%cN "$commit")" check_name "Author" "$author_name" check_name "Committer" "$committer_name" - author_email="$(git show -s --format='<%aE>' "$commit")" + author_email="$(git "${REPO_PATH[@]}" show -s --format='<%aE>' "$commit")" check_author_email "$author_email" - subject="$(git show -s --format=%s "$commit")" + subject="$(git "${REPO_PATH[@]}" show -s --format=%s "$commit")" echo info 'Checking subject:' echo "$subject" check_subject "$subject" "$author_email" - body="$(git show -s --format=%b "$commit")" - sob="$(git show -s --format='Signed-off-by: %aN <%aE>' "$commit")" + body="$(git "${REPO_PATH[@]}" show -s --format=%b "$commit")" + sob="$(git "${REPO_PATH[@]}" show -s --format='Signed-off-by: %aN <%aE>' "$commit")" echo info 'Checking body:' echo "$body" From f43f8a053d6180c2bd1919d3f5ac9ad68f50800c Mon Sep 17 00:00:00 2001 From: George Sapkin Date: Mon, 1 Dec 2025 05:32:36 +0200 Subject: [PATCH 2/5] formal: add a link to actions repo Suggest users to provide feedback in case of issues by linking the actions repo at the top of the output and at the bottom of the summary comment. Reformat URLs for readability. Signed-off-by: George Sapkin --- .github/scripts/check_formalities.sh | 6 ++++++ .github/scripts/process_formalities.js | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/scripts/check_formalities.sh b/.github/scripts/check_formalities.sh index eb7a379b..bc23f22c 100755 --- a/.github/scripts/check_formalities.sh +++ b/.github/scripts/check_formalities.sh @@ -225,6 +225,12 @@ main() { # Initialize GitHub actions output output 'content< > Some formality checks failed. > -> Consider (re)reading [submissions guidelines](https://openwrt.org/submitting-patches#submission_guidelines). +> Consider (re)reading [submissions guidelines]( +https://openwrt.org/submitting-patches#submission_guidelines).
Failed checks @@ -52,7 +55,13 @@ const NO_MODIFY=` > > PR has _Allow edits and access to secrets by maintainers_ disabled. Consider allowing edits to simplify review. > -> [More info](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork) +> [More info]( +https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork) +`; + +const FEEDBACK=` +Something broken? Consider [providing feedback]( +https://github.com/openwrt/actions-shared-workflows/issues). `; async function hideOldSummaries({ github, owner, repo, issueNumber }) { @@ -86,6 +95,7 @@ function getCommentMessage({ context, jobId, noModify, summary }) { return ` ${summary.length > 0 ? getSummaryMessage({ context, jobId, summary }) : ''} ${noModify ? NO_MODIFY : ''} + ${FEEDBACK} ${COMMENT_LOOKUP} `; } From 5911fd6bd8bf100b8e7d4541eed0bca3864fdb35 Mon Sep 17 00:00:00 2001 From: George Sapkin Date: Mon, 15 Dec 2025 16:14:08 +0200 Subject: [PATCH 3/5] formal: add committer email check Check committer email for GitHub noreply address. Signed-off-by: George Sapkin --- .github/scripts/check_formalities.sh | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/scripts/check_formalities.sh b/.github/scripts/check_formalities.sh index bc23f22c..fb8565bf 100755 --- a/.github/scripts/check_formalities.sh +++ b/.github/scripts/check_formalities.sh @@ -6,7 +6,8 @@ MAX_SUBJECT_LEN_HARD=60 MAX_SUBJECT_LEN_SOFT=50 MAX_BODY_LINE_LEN=75 -WEBLATE_EMAIL="" +GITHUB_NOREPLY_EMAIL='@users.noreply.github.com' +WEBLATE_EMAIL='' EMOJI_WARN=':large_orange_diamond:' EMOJI_FAIL=':x:' @@ -96,14 +97,15 @@ check_name() { fi } -check_author_email() { - local email="$1" +check_email() { + local type="$1" + local email="$2" - if echo "$email" | grep -qF "@users.noreply.github.com"; then - output_fail 'Author email cannot be a GitHub noreply email' + if echo "$email" | grep -qF "$GITHUB_NOREPLY_EMAIL"; then + output_fail "$type email cannot be a GitHub noreply email" RET=1 else - status_pass 'Author email is not a GitHub noreply email' + status_pass "$type email is not a GitHub noreply email" fi } @@ -191,7 +193,7 @@ check_body() { RET=1 fi - if echo "$body" | grep -qF "@users.noreply.github.com"; then + if echo "$body" | grep -qF "$GITHUB_NOREPLY_EMAIL"; then output_fail '`Signed-off-by` email cannot be a GitHub noreply email' RET=1 else @@ -250,11 +252,12 @@ main() { author_name="$(git "${REPO_PATH[@]}" show -s --format=%aN "$commit")" committer_name="$(git "${REPO_PATH[@]}" show -s --format=%cN "$commit")" - check_name "Author" "$author_name" - check_name "Committer" "$committer_name" - author_email="$(git "${REPO_PATH[@]}" show -s --format='<%aE>' "$commit")" - check_author_email "$author_email" + committer_email="$(git "${REPO_PATH[@]}" show -s --format='<%cE>' "$commit")" + check_name 'Author' "$author_name" + check_email 'Author' "$author_email" + check_name 'Committer' "$committer_name" + check_email 'Committer' "$committer_email" subject="$(git "${REPO_PATH[@]}" show -s --format=%s "$commit")" echo From 91a56b4b0040e33d2fd49be2cd4cf1e2f24c691a Mon Sep 17 00:00:00 2001 From: George Sapkin Date: Mon, 15 Dec 2025 15:56:19 +0200 Subject: [PATCH 4/5] formal: exclude dependabot from some checks Exclude dependabot commits by default from the same formality checks as Weblate. Signed-off-by: George Sapkin --- .github/scripts/check_formalities.sh | 77 +++++++++++++++++++++------- .github/workflows/formal.yml | 6 +++ 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/.github/scripts/check_formalities.sh b/.github/scripts/check_formalities.sh index fb8565bf..8b56adff 100755 --- a/.github/scripts/check_formalities.sh +++ b/.github/scripts/check_formalities.sh @@ -6,6 +6,7 @@ MAX_SUBJECT_LEN_HARD=60 MAX_SUBJECT_LEN_SOFT=50 MAX_BODY_LINE_LEN=75 +DEPENDABOT_EMAIL="dependabot[bot]@users.noreply.github.com" GITHUB_NOREPLY_EMAIL='@users.noreply.github.com' WEBLATE_EMAIL='' @@ -70,10 +71,18 @@ is_stable_branch() { [ "$1" != "main" ] && [ "$1" != "master" ] } +is_dependabot() { + echo "$1" | grep -iqF "$DEPENDABOT_EMAIL" +} + is_weblate() { echo "$1" | grep -iqF "$WEBLATE_EMAIL" } +exclude_dependabot() { + [ "$EXCLUDE_DEPENDABOT" = 'true' ] +} + exclude_weblate() { [ "$EXCLUDE_WEBLATE" = 'true' ] } @@ -81,10 +90,15 @@ exclude_weblate() { check_name() { local type="$1" local name="$2" + local email="$3" + if exclude_dependabot && is_dependabot "$email"; then + status_warn "$type email exception: authored by dependabot" + elif exclude_weblate && is_weblate "$email"; then + status_warn "$type email exception: authored by Weblate" # Pattern \S\+\s\+\S\+ matches >= 2 names i.e. 3 and more e.g. "John Von # Doe" also match - if echo "$name" | grep -q '\S\+\s\+\S\+'; then + elif echo "$name" | grep -q '\S\+\s\+\S\+'; then status_pass "$type name ($name) seems OK" # Pattern \S\+ matches single names, typical of nicknames or handles elif echo "$name" | grep -q '\S\+'; then @@ -101,7 +115,11 @@ check_email() { local type="$1" local email="$2" - if echo "$email" | grep -qF "$GITHUB_NOREPLY_EMAIL"; then + if exclude_dependabot && is_dependabot "$email"; then + status_warn "$type email exception: authored by dependabot" + elif exclude_weblate && is_weblate "$email"; then + status_warn "$type email exception: authored by Weblate" + elif echo "$email" | grep -qF "$GITHUB_NOREPLY_EMAIL"; then output_fail "$type email cannot be a GitHub noreply email" RET=1 else @@ -114,7 +132,9 @@ check_subject() { local author_email="$2" # Check subject format - if exclude_weblate && echo "$subject" | grep -iq -e '^Translated using Weblate.*' -e '^Added translation using Weblate.*'; then + if exclude_dependabot && is_dependabot "$author_email"; then + status_warn 'Commit subject line exception: authored by dependabot' + elif exclude_weblate && is_weblate "$author_email"; then status_warn 'Commit subject line exception: authored by Weblate' elif echo "$subject" | grep -qE -e '^([0-9A-Za-z,+/._-]+: )+[a-z]' -e '^Revert '; then status_pass 'Commit subject line format seems OK' @@ -136,9 +156,12 @@ check_subject() { RET=1 fi - if exclude_weblate && is_weblate "$author_email"; then - # Don't append to the workflow output, since this is more of an internal - # warning. + # Don't append to the workflow output, since these are more of internal + # warnings. + if exclude_dependabot && is_dependabot "$author_email"; then + status_warn 'Commit subject line length exception: authored by dependabot' + return + elif exclude_weblate && is_weblate "$author_email"; then status_warn 'Commit subject line length exception: authored by Weblate' return fi @@ -165,7 +188,7 @@ check_body() { local author_email="$3" # Check body line lengths - if ! exclude_weblate || ! is_weblate "$author_email"; then + if ! { exclude_weblate && is_weblate "$author_email"; } && ! { exclude_dependabot && is_dependabot "$author_email"; }; then body_line_too_long=0 line_num=0 while IFS= read -r line; do @@ -180,24 +203,36 @@ check_body() { if [ "$body_line_too_long" = 0 ]; then status_pass "Commit body lines are $MAX_BODY_LINE_LEN characters or less" fi + else + if exclude_dependabot && is_dependabot "$author_email"; then + status_warn 'Commit body line length exception: authored by dependabot' + elif exclude_weblate && is_weblate "$author_email"; then + status_warn 'Commit body line length exception: authored by Weblate' + fi fi if echo "$body" | grep -qF "$sob"; then status_pass '`Signed-off-by` matches author' + + # Don't append to the workflow output, since these are more of internal + # warnings. + elif exclude_dependabot && is_dependabot "$author_email"; then + status_warn '`Signed-off-by` exception: authored by dependabot' elif exclude_weblate && is_weblate "$author_email"; then - # Don't append to the workflow output, since this is more of an internal - # warning. status_warn '`Signed-off-by` exception: authored by Weblate' + else output_fail "\`Signed-off-by\` is missing or doesn't match author (should be \`$sob\`)" RET=1 fi - if echo "$body" | grep -qF "$GITHUB_NOREPLY_EMAIL"; then - output_fail '`Signed-off-by` email cannot be a GitHub noreply email' - RET=1 - else - status_pass '`Signed-off-by` email is not a GitHub noreply email' + if ! ( exclude_dependabot && is_dependabot "$author_email" ) && ! ( exclude_weblate && is_weblate "$author_email" ); then + if echo "$body" | grep -qF "$GITHUB_NOREPLY_EMAIL"; then + output_fail '`Signed-off-by` email cannot be a GitHub noreply email' + RET=1 + else + status_pass '`Signed-off-by` email is not a GitHub noreply email' + fi fi if echo "$body" | grep -v "Signed-off-by:" | grep -qv '^[[:space:]]*$'; then @@ -233,10 +268,16 @@ main() { EOF + if exclude_dependabot; then + warn 'dependabot exceptions are enabled' + else + echo 'dependabot exceptions are disabled' + fi + if exclude_weblate; then - warn "Weblate exceptions are enabled" + warn 'Weblate exceptions are enabled' else - echo "Weblate exceptions are disabled" + echo 'Weblate exceptions are disabled' fi echo @@ -254,9 +295,9 @@ main() { committer_name="$(git "${REPO_PATH[@]}" show -s --format=%cN "$commit")" author_email="$(git "${REPO_PATH[@]}" show -s --format='<%aE>' "$commit")" committer_email="$(git "${REPO_PATH[@]}" show -s --format='<%cE>' "$commit")" - check_name 'Author' "$author_name" + check_name 'Author' "$author_name" "$author_email" check_email 'Author' "$author_email" - check_name 'Committer' "$committer_name" + check_name 'Committer' "$committer_name" "$committer_email" check_email 'Committer' "$committer_email" subject="$(git "${REPO_PATH[@]}" show -s --format=%s "$commit")" diff --git a/.github/workflows/formal.yml b/.github/workflows/formal.yml index 9f76b360..17e88e81 100644 --- a/.github/workflows/formal.yml +++ b/.github/workflows/formal.yml @@ -3,6 +3,11 @@ name: Test Formalities on: workflow_call: inputs: + exclude_dependabot: + description: 'Exclude commits authored by dependabot from some checks' + default: true + required: false + type: boolean exclude_weblate: description: 'Exclude commits authored by Weblate from some checks' required: false @@ -47,6 +52,7 @@ jobs: run: workflow_context/.github/scripts/check_formalities.sh env: BRANCH: ${{ github.base_ref }} + EXCLUDE_DEPENDABOT: ${{ inputs.exclude_dependabot }} EXCLUDE_WEBLATE: ${{ inputs.exclude_weblate }} - name: Process GitHub formality check results From d6f5660c07f25166e345f56044213162624d20fe Mon Sep 17 00:00:00 2001 From: George Sapkin Date: Mon, 15 Dec 2025 16:29:46 +0200 Subject: [PATCH 5/5] formal-this-repo: set correct event trigger Fix the formal-this-repo event trigger to allow posting comments to PRs from forks. Fixes: 1079ad9 ("formal: post summary to the PR") Fixes: 6d06d51 ("formal-this-repo: post results to the PR") Signed-off-by: George Sapkin --- .github/workflows/formal-this-repo.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/formal-this-repo.yaml b/.github/workflows/formal-this-repo.yaml index 1cbe84ac..e5096c4d 100644 --- a/.github/workflows/formal-this-repo.yaml +++ b/.github/workflows/formal-this-repo.yaml @@ -1,7 +1,7 @@ name: Test Formalities on: - pull_request: + pull_request_target: permissions: contents: read