-
Notifications
You must be signed in to change notification settings - Fork 191
ci: new workflow for sending emails after merging a PR #4184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
name: Send emails for merged PR | ||
|
||
on: | ||
pull_request: | ||
types: | ||
- closed | ||
branches: | ||
- "master" | ||
|
||
jobs: | ||
send_patches: | ||
if: github.event.pull_request.merged == true | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout repo with full history | ||
uses: actions/checkout@v5 | ||
with: | ||
fetch-depth: 100 | ||
|
||
- name: Install deps (git send-email and jq) | ||
run: | | ||
sudo apt-get update | ||
sudo apt-get install -y jq | ||
|
||
## GHA images have a special git package that conflicts with | ||
## git-send-email So this is a workaround to force the installation of | ||
## the conflicting package. | ||
sudo apt-get install -y libauthen-sasl-perl \ | ||
libemail-valid-perl \ | ||
libio-socket-ssl-perl \ | ||
libmailtools-perl perl \ | ||
libnet-smtp-ssl-perl | ||
|
||
apt-get download git-email | ||
sudo dpkg -i --force-all git-email*deb | ||
|
||
- name: Configure git identity | ||
run: | | ||
git config user.name "gccrs gerris bot" | ||
git config user.email "${{ secrets.SMTP_FROM }}" | ||
|
||
- name: Export env | ||
env: | ||
GH_EVENT: ${{ toJson(github.event) }} | ||
run: | | ||
echo "$GH_EVENT" > /tmp/gh_event.json | ||
|
||
PR_BASE_REF=$(jq -r '.pull_request.base.sha' /tmp/gh_event.json) | ||
echo "PR_BASE_REF=$PR_BASE_REF" >> $GITHUB_ENV | ||
|
||
PR_NUMBER=$(jq -r '.pull_request.number' /tmp/gh_event.json) | ||
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV | ||
|
||
PR_TITLE=$(jq -r '.pull_request.title' /tmp/gh_event.json) | ||
echo "PR_TITLE=$PR_TITLE" >> $GITHUB_ENV | ||
|
||
PR_URL=$(jq -r '.pull_request.html_url' /tmp/gh_event.json) | ||
echo "PR_URL=$PR_URL" >> $GITHUB_ENV | ||
|
||
PR_MERGE_COMMIT=$(jq -r '.pull_request.merge_commit_sha' /tmp/gh_event.json) | ||
echo "PR_MERGE_COMMIT=$PR_MERGE_COMMIT" >> $GITHUB_ENV | ||
|
||
PR_TARGET_BRANCH=$(jq -r '.pull_request.base.ref' /tmp/gh_event.json) | ||
echo "PR_TARGET_BRANCH=$PR_TARGET_BRANCH" >> $GITHUB_ENV | ||
|
||
PR_LABELS=$(jq -r '[.pull_request.labels[].name] | join(",")' /tmp/gh_event.json) | ||
echo "PR_LABELS=$PR_LABELS" >> $GITHUB_ENV | ||
|
||
REPO_SSH=$(jq -r '.repository.ssh_url' /tmp/gh_event.json) | ||
echo "REPO_SSH=$REPO_SSH" >> $GITHUB_ENV | ||
|
||
echo "SERIES_DIR=/tmp/series" >> $GITHUB_ENV | ||
|
||
- name: Check for label 'no-ml' to skip sending emails | ||
run: | | ||
# Skip if PR has label "no-ml" | ||
if echo "$PR_LABELS" | grep -qiE "(^|,)no-ml(,|$)"; then | ||
echo "Opt-out label present: skipping mailing list." | ||
echo "Opt-out label present: skipping mailing list." > $GITHUB_STEP_SUMMARY | ||
exit 0 | ||
fi | ||
|
||
- name: Get commit list from PR and skip the internal ones | ||
id: commits | ||
run: | | ||
# Skip commits that touches any of these | ||
patterns=(".github/" | ||
"CODE_OF_CONDUCT.md" | ||
"CONTRIBUTING.md" | ||
"Dockerfile" | ||
"README.md" | ||
"logo.png" | ||
"gcc/rust/gource-gccrs.sh" | ||
"gcc/rust/monthly-diff.py" | ||
) | ||
regex=$(printf '%s\n' "${patterns[@]}" | sed -e 's/[.[\*^$+?(){|\/\\]/\\&/g' | paste -sd'|' -) | ||
|
||
rm -f /tmp/commits.txt | ||
|
||
git log --format="%H" "$PR_BASE_REF..HEAD" | while read SHA1; do | ||
if grep -q -E "$regex" <(git diff-tree --no-commit-id --name-only -r "$SHA1"); then | ||
echo "Touching something not to be upstreamed, skipping commit $SHA1" | ||
else | ||
echo "$SHA1" >> /tmp/commits.txt | ||
fi | ||
done | ||
|
||
COUNT=$(wc -l < /tmp/commits.txt) | ||
echo "COUNT=$COUNT" >> $GITHUB_ENV | ||
|
||
- name: Check what to do based on series' size | ||
run: | | ||
MAX=150 | ||
if [ "${COUNT}" -gt "$MAX" ]; then | ||
echo "Series has $COUNT commits (> $MAX). Not doing anything" >> $GITHUB_STEP_SUMMARY | ||
exit 0 | ||
else if [ "${COUNT}" -eq 1 ]; then | ||
echo "Single commit PR, don't do the cover letter" | ||
echo "DO_COVER=0" >> $GITHUB_ENV | ||
else | ||
echo "Multiple commits ($COUNT) in PR, create a cover letter" | ||
echo "DO_COVER=1" >> $GITHUB_ENV | ||
fi fi | ||
|
||
- name: Prepare patch series | ||
run: | | ||
set -euo pipefail | ||
|
||
# Create a temporary branch that linearizes the PR commits | ||
git checkout -B ci-mail-patches "$PR_BASE_REF" | ||
# Cherry-pick commits in the exact PR order (no-commit to batch, then commit) | ||
while read sha; do | ||
git cherry-pick "$sha" | ||
done < /tmp/commits.txt | ||
|
||
# Build cover letter text | ||
N="${COUNT:-0}" | ||
TITLE="$(printf '[PATCH 0/%d] PR #%s: %s' "$N" "$PR_NUMBER" "$PR_TITLE")" | ||
|
||
echo "PR: $PR_URL" > /tmp/description.txt | ||
echo "Merged by: ${{ github.actor }}" >> /tmp/description.txt | ||
echo "Base: $PR_TARGET_BRANCH" >> /tmp/description.txt | ||
echo "" >> /tmp/description.txt | ||
echo "This series was merged into the gccrs repository and is posted here for" >> /tmp/description.txt | ||
echo "upstream visibility and potential drive-by review, as requested by GCC" >> /tmp/description.txt | ||
echo "release managers." >> /tmp/description.txt | ||
echo "" >> /tmp/description.txt | ||
echo " Notes:" >> /tmp/description.txt | ||
echo " - Source branch: $(jq -r '.pull_request.head.label' /tmp/gh_event.json)" >> /tmp/description.txt | ||
echo " - Merge commit: $PR_MERGE_COMMIT" >> /tmp/description.txt | ||
echo " - Commit count: $N" >> /tmp/description.txt | ||
echo "" >> /tmp/description.txt | ||
|
||
mkdir /tmp/series | ||
|
||
if [ "$DO_COVER" = "1" ]; then | ||
# Generate series + cover letter | ||
git format-patch \ | ||
--subject-prefix="gccrs COMMIT" \ | ||
--cover-letter \ | ||
--description-file=/tmp/description.txt \ | ||
--base="$PR_BASE_REF" \ | ||
--output-directory /tmp/series \ | ||
"$PR_BASE_REF"..HEAD | ||
|
||
awk -v CONTENT="$PR_TITLE" '{gsub(/\*\*\* SUBJECT HERE \*\*\*/, CONTENT); print}' /tmp/series/0000-cover-letter.patch > /tmp/temp | ||
mv /tmp/temp /tmp/series/0000-cover-letter.patch | ||
else | ||
# Generate series + cover letter | ||
git format-patch \ | ||
--subject-prefix="gccrs COMMIT" \ | ||
--no-cover-letter \ | ||
--base="$PR_BASE_REF" \ | ||
--output-directory /tmp/series \ | ||
"$PR_BASE_REF"..HEAD | ||
|
||
# for every patch file, insert the github header right after the '---'. | ||
sed '/^---$/ r /tmp/description.txt' -i /tmp/series/* | ||
fi | ||
|
||
- name: Send series via git send-email | ||
env: | ||
GIT_SMTP_SERVER: ${{ secrets.SMTP_SERVER }} | ||
GIT_SMTP_ENCRYPTION: tls | ||
GIT_SMTP_SERVER_PORT: ${{ secrets.SMTP_PORT }} | ||
GIT_SMTP_AUTH: "true" | ||
GIT_SMTP_USER: ${{ secrets.SMTP_USERNAME }} | ||
GIT_SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }} | ||
FROM: ${{ secrets.SMTP_FROM }} | ||
TO: ${{ secrets.PATCH_TO }} | ||
CC: ${{ secrets.PATCH_CC }} | ||
run: | | ||
set -euo pipefail | ||
|
||
git config sendemail.smtpserver "$GIT_SMTP_SERVER" | ||
git config sendemail.smtpserverport "$GIT_SMTP_SERVER_PORT" | ||
git config sendemail.smtpencryption "$GIT_SMTP_ENCRYPTION" | ||
git config sendemail.smtpuser "$GIT_SMTP_USER" | ||
git config sendemail.smtppass "$GIT_SMTP_PASSWORD" | ||
git config sendemail.from "$FROM" | ||
git config sendemail.to "$TO" | ||
if [ -n "${CC:-}" ]; then git config sendemail.cc "$CC"; fi | ||
git config sendemail.thread "true" | ||
git config sendemail.confirm "never" | ||
git config sendemail.annotate "false" | ||
|
||
git send-email /tmp/series/* |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.